I keep running into this error in my application_controller and I can't seem to figure out the issue.
Everything seems to work fine until I have to edit a gig. I know I'll need to refactor my code or else I will run into this issue again.
Any help is appreciated!
Error-
NoMethodError at /gigs/:id/edit
undefined method `user_id' for nil:NilClass
Application Controller
require './config/environment'
class ApplicationController < Sinatra::Base
configure do
set :public_folder, 'public'
set :views, 'app/views'
enable :sessions
set :session_secret, "secret"
end
get "/" do
erb :welcome
end
get "/signup" do
erb :'/users/signup'
end
post "/signup" do
if User.find_by(:email => params["email"])
puts "Sorry, there is already an account using this email address"
redirect "/login"
else
user = User.create(params)
if user.save
session[:user_id] = user.id
redirect "/"
else
puts "Sorry. All fields must be filled out."
redirect "/signup"
end
end
# #user = User.new(name: params["name"], email: params["email"], password: params["password"])
# #user.save
##user = User.new(params)
# #user.save
#session[:user_id] = #user.id
#puts params
#redirect '/users/home'
#session[:name] = params[:name]
end
get "/login" do
erb :'users/login'
end
post '/login' do
#user = User.find_by(:email => params["email"])
if #user && #user.authenticate(params["password"])
session[:user_id] = #user.id
redirect "/home"
end
redirect "/login"
end
get '/home' do
#user = User.find(session[:user_id])
erb :'users/home'
end
get '/gigs' do
if Helpers.is_logged_in?(session)
#user = Helpers.current_user(session)
#gigs = Gig.all
#if #user != nil
# #gigs = Gig.where(:user_id => #user.id)
erb :'gigs/index'
else
redirect "/login"
end
end
post '/gigs' do
#user = Helpers.current_user(session)
#gig = #user.gigs.create(params)
if #gig.save
puts "Gig has been saved."
else
puts "Please try again."
end
redirect "/gigs"
end
get '/gigs/new' do
if Helpers.is_logged_in?(session)
erb :'gigs/new'
else
redirect "/login"
end
end
get '/gigs/:id' do
if Helpers.is_logged_in?(session)
#user = Helpers.current_user(session)
#gig = Gig.find_by_id(params["id"])
if #gig.id == #gig.user_id
erb :'gigs/show'
else
redirect "/login"
end
else
redirect "/login"
end
end
get '/gigs/:id/edit' do
if Helpers.is_logged_in?(session)
#user = Helpers.current_user(session)
#gig = Gig.find_by_id(params[:id]) #["id"]
if #user.id == #gig.user_id
erb :'gigs/edit'
else
redirect "/login"
end
else
redirect "/login"
end
end
patch '/gigs/:id' do
#user = Helpers.current_user(session)
#gig = Gig.find_by_id(params["id"])
if #user.id == #gig.user_id
#gig.update(params["gig"])
redirect "/gigs/#{#gig.id}"
else
redirect "/login"
end
end
delete '/gigs/:id' do
#user = Helpers.current_user(session)
#gig = Gig.find_by_id(params["id"])
if #user.id == #gig.user_id
#gig.destroy
redirect "/gigs"
else
redirect "/login"
end
end
get '/logout' do
session.clear
redirect "/"
end
end
Helpers.rb
class Helpers
def self.is_logged_in?(session)
if session[:user_id] != nil
true
else
false
end
end
def self.current_user(session)
if self.is_logged_in?(session)
#user = User.find_by_id(session[:user_id])
end
end
end
Schema
ActiveRecord::Schema.define(version: 20200209173236) do
create_table "genres", force: :cascade do |t|
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "gigs", force: :cascade do |t|
t.string "bands"
t.string "location"
t.date "date"
t.string "time"
t.integer "user_id"
end
create_table "users", force: :cascade do |t|
t.string "name"
t.string "email"
t.string "password_digest"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
end
error log-
D, [2020-02-10T08:58:54.511675 #10068] DEBUG -- : ActiveRecord::SchemaMigration Load (0.1ms) SELECT "schema_migrations".* FROM "schema_migrations"
D, [2020-02-10T08:58:54.536858 #10068] DEBUG -- : User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 3]]
D, [2020-02-10T08:58:54.550769 #10068] DEBUG -- : Gig Load (0.1ms) SELECT "gigs".* FROM "gigs" WHERE "gigs"."id" = ? LIMIT 1 [["id", 0]]
2020-02-10 08:58:54 - NoMethodError - undefined method `user_id' for nil:NilClass:
/Users/melc/nyc-shows/app/controllers/application_controller.rb:115:in `block in <class:ApplicationController>'
According to the query
SELECT "gigs".* FROM "gigs" WHERE "gigs"."id" = ? LIMIT 1 [["id", 0]]
The ID you are trying to find is Zero so #gig is null (unless you really have a record with id 0)
#gig = Gig.find_by_id(params["id"])
if #user.id == #gig.user_id
You can protect against this like so
if #gig.nil? || #user.id == #gig.user_id
but my guess the issue is in the generation of the url rather than this method.
Also you can probably refactor the function more like this
get '/gigs/:id/edit' do
#user = Helpers.current_user(session)
#gig = Gig.find_by_id(params[:id])
redirect "/login" if #user.nil?
redirect "/invalid_gig_page" if #gig.nil? || #user.id != #gig.user_id
erb :'gigs/edit'
end
Related
I'm trying to "edit a gig" on my app but it's giving me the error that the gig has no user_id. Creating a new gig is no issue. I feel like it's just poor syntax I didn't look over correctly but I have no idea. I've tried everything.
NoMethodError at /gigs/:id/edit
undefined method `user_id' for nil:NilClass
file: gigs_controller.rb location: block in <class:GigController> line: 43
Below is my App Controller, Gig Controller, schema, and log.
Thanks!
APP CONTROLLER
require './config/environment'
class ApplicationController < Sinatra::Base
configure do
set :public_folder, 'public'
set :views, 'app/views'
enable :sessions
set :session_secret, "secret"
end
get '/' do
erb :welcome
end
get '/logout' do
session.clear
redirect to '/'
end
#helpers
helpers do
def logged_in?
!!current_user
end
def current_user
User.find_by_id(session[:user_id])
end
def is_authorized?(id)
current_user.id == id.to_i
end
end
end
GIG CONTROLLER
class GigController < ApplicationController
get '/gigs' do
if logged_in?
#gigs = Gig.all
erb :'/gigs/index'
else
redirect to '/signup'
end
end
get '/gigs/new' do
if logged_in?
#gigs = Gig.all
erb :'gigs/new'
else
redirect to '/login'
end
end
post '/gigs' do
if logged_in?
#gig = current_user.gigs.create(bands: params[:bands], location: params[:location], date: params[:date], time: params[:time])
"Event has been added."
redirect "/gigs"
else
"When creating a new Event, please provide Artists, a Location, a date and a time."
redirect '/gigs'
end
end
get '/gigs/:id' do
if logged_in?
#gig = Gig.find(params[:id])
erb :"gigs/show"
else
redirect '/login'
end
end
get '/gigs/:id/edit' do
if logged_in?
#gig = Gig.find(params[:id])
if current_user.id == #gig.user_id
erb :"gigs/edit"
else
"You are not authorized to edit this Event."
redirect to '/login'
end
end
end
end
SCHEMA-
ActiveRecord::Schema.define(version: 20200209173236) do
create_table "genres", force: :cascade do |t|
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "gigs", force: :cascade do |t|
t.string "bands"
t.string "location"
t.date "date"
t.string "time"
t.integer "user_id"
end
create_table "users", force: :cascade do |t|
t.string "name"
t.string "email"
t.string "password_digest"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
end
ERROR-
D, [2020-02-10T13:53:35.237402 #11377] DEBUG -- : ActiveRecord::SchemaMigration Load (0.1ms) SELECT "schema_migrations".* FROM "schema_migrations"
D, [2020-02-10T13:53:35.257906 #11377] DEBUG -- : User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 4]]
D, [2020-02-10T13:53:35.262209 #11377] DEBUG -- : Gig Load (0.1ms) SELECT "gigs".* FROM "gigs" WHERE "gigs"."id" = ? LIMIT 1 [["id", nil]]
2020-02-10 13:53:35 - ActiveRecord::RecordNotFound - Couldn't find Gig with 'id'=:
/Users/melc/.rvm/gems/ruby-2.6.1/gems/activerecord-4.2.11.1/lib/active_record/core.rb:155:in `find'
/Users/melc/nyc-shows/app/controllers/gigs_controller.rb:42:in `block in <class:GigController>'
We are building a scheduling app in class, and attempting to create a function to allow for the copying of a previous shift, and all employees under that shift to the next week of scheduling. Here is my code currently:
def copy
set_calendar
#past_shift = Shift.find(params[:id])
if #calendar.users.owners.include?(current_user) || #calendar.users.managers.include?(current_user)
#shift = #past_shift.clone
if #shift.save
render json: ("Shift copied successfully"), status: :ok
else
render json: #usershift.errors, status: :uprocessable_entity
end
else
render json: ("You do not have access to copy shifts"), status: :unauthorized
end
end
I've used both .clone and .dup, but it seems it only copies the shifts over, without copying the employees associated with those shifts. Any help or guidance in the right path would be appreciated.
Below is the entire controller for shifts:
class ShiftsController < ApplicationController
def index
set_calendar
if params["start_date"] && params["end_date"]
start_date = params["start_date"].to_date
end_date = params["end_date"].to_date
if #calendar.users.include?(current_user)
#shifts = Shift.where(
calendar_id: #calendar.id,
start_time: start_date.beginning_of_day .. end_date.end_of_day)
render "/shifts/index.json", status: :ok
else
render json: '{}', status: :unauthorized
end
else
render json: {'error': 'start date and end date are required'}, status: :unprocessable_entity
end
end
def myschedule
#user = User.find(params[:user_id])
#publishedshifts = #user.shifts.where(published: true)
if #user
render "/shifts/index2.json", status: :ok
else
render json: ('You do not have access to these shifts'), status: :unauthorized
end
end
def create
set_calendar
if #calendar.users.owners.include?(current_user) || #calendar.users.managers.include?(current_user)
#shift = Shift.new(shift_params)
if #shift.save
render "/shifts/create.json", status: :ok
else
render json: #shift.errors
end
else render json: ('You do not have access to create a shift.'), status: :unauthorized
end
end
def copy
set_calendar
#past_shift = Shift.find(params[:id])
if #calendar.users.owners.include?(current_user) || #calendar.users.managers.include?(current_user)
#shift = #past_shift.clone
if #shift.save
render json: ("Shift copied successfully"), status: :ok
else
render json: #usershift.errors, status: :uprocessable_entity
end
else
render json: ("You do not have access to copy shifts"), status: :unauthorized
end
end
def update
set_calendar
set_shift
if #calendar.users.owners.include?(current_user) || #calendar.users.managers.include?(current_user)
if #shift.update_attributes(shift_params)
render "/shifts/update.json", status: :ok
else
render json: #shift.errors, status: :uprocessable_entity
end
else render json: ("You don't have access to update shifts."), status: :unauthorized
end
end
def destroy
set_calendar
set_shift
if #calendar.users.owners.include?(current_user) || #calendar.users.managers.include?(current_user)
if #shift.destroy
render json: ("Shift deleted!"), status: :ok
else
render json: #shift.errors, status: :uprocessable_entity
end
else render json: ("You don't have access to delete shifts.")
end
end
private
def set_calendar
#calendar = Calendar.find(params[:calendar_id])
end
def set_shift
#shift = Shift.find(params[:id])
end
def shift_params
params.permit(:start_time, :end_time, :calendar_id, :capacity, :published)
end
end
Schema:
create_table "users", force: :cascade do |t|
t.string "email"
t.string "phone_number"
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "password_digest"
t.string "api_token"
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
end
create_table "usershifts", force: :cascade do |t|
t.bigint "user_id"
t.bigint "shift_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["shift_id"], name: "index_usershifts_on_shift_id"
t.index ["user_id"], name: "index_usershifts_on_user_id"
end
create_table "shifts", force: :cascade do |t|
t.datetime "start_time"
t.datetime "end_time"
t.bigint "calendar_id"
t.integer "capacity"
t.boolean "published"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["calendar_id"], name: "index_shifts_on_calendar_id"
end
Ok, I suppose you don't want to clone user records when cloning shift. Also, based on the migrations, it seems that Shift and User models are connected through usershifts table, ie Shift model has_many :users, through :usershifts.
If so, the code can be:
#shift = #past_shift.dup
#shift.users = #past_shift.users
if #shift.save
...
else
...
end
#past_shift.dup returns a duplicate of the record that hasn't been assigned an id yet and is treated as a new record. #shift.users = #past_shift.users copies associated users (it does not create new records in users but only in join table usershifts, and these records are not saved yet). #shift.save saves it all :)
I am trying to add a search bar. I have also set the path. But everytime I try to click on search it directs me to this error. What is the error in this code?
This is my Inbox_Controller file. It says that the action 'Search' cannot be found in InboxController.
class InboxController < ApplicationController
before_action :valid_membership
before_action :change_password_next_login
before_action :agreed_to_terms
before_action :allowed_send_mail?
layout 'inbox'
def bulk
puts params
ids = params[:bulk_ids]
if ids
params[:commit]
case params[:commit]
when 'Archive'
ids.each do |id|
message = Message.find(id)
message.archived = true
message.save()
end
when 'Restore'
ids.each do |id|
message = Message.find(id)
message.archived = false
message.save()
end
else
puts 'invalid action!!'
end
if params[:folder] != ''
redirect_to inbox_index_path(folder: params[:folder])
else
redirect_to inbox_index_path
end
else
flash[:alert] = t('errors.inbox.no_emails_selected')
redirect_to :back
end
end
def index
per_page = 10
page = params[:page] ? params[:page] : 1
#inbox = Inbox.search(params[:search])
case params[:folder]
when 'archive'
#messages = current_user.archived_messages(page, per_page)
when 'drafts'
#messages = current_user.draft_messages(page, per_page)
when 'sent'
#messages = current_user.sent_messages(page, per_page)
else
#messages = current_user.received_messages(page, per_page)
end
end
def reply
original = Message.find(params[:id])
#quoted = "\n\nOn #{original.sent_time.strftime("%m/%d/%y %-I:%M %p")}, # {original.from.full_name} wrote:\n----------------\n#{original.body}"
#message = Message.new(
:parent => original,
:to => original.from,
:subject => "RE: #{original.subject}",
:body => #quoted,
)
render :compose
end
def move
#message = Message.find(params[:id])
folder = params[:destination]
case folder
when 'archive'
#message.archived = true
else
#message.archived = false
end
unless #message.save
puts #message.errors.full_messages
end
redirect_to inbox_index_path(folder: folder)
end
def show
#message = Message.find(params[:id])
if !#message.read? && #message.to == current_user
#message.read_time = DateTime.now
unless #message.save
puts #message.errors.full_messages
end
end
end
def edit
#message = Message.find(params[:id])
#message.to_name = #message.to.full_name
render 'compose'
end
def compose
#message = Message.new
if(params[:id])
#message.to = Mentor.find(params[:id])
end
end
def create
if(params[:message] && !params[:message][:id].empty?)
#message = Message.find(params[:message][:id])
#message.assign_attributes(message_params)
else
#message = Message.new(message_params)
end
if params[:parent_id] && !params[:parent_id].empty?
#message.parent = Message.find(params[:parent_id])
#message.replied_to_time = Time.now
end
#message.from = current_user
draft = params[:draft]
if draft
#message.draft = true
else
#message.sent_time = Time.now
#message.draft = false
end
# puts #message.as_json
if can_send_mail
if #message.save
if !draft
if current_user_or_guest.mentee?
current_user.credits += -1
current_user.save
end
UserMailer.inmail_notification(#message).deliver
end
redirect_to inbox_index_path(folder: draft ? 'drafts' : 'inbox'), notice: "Message successfully #{draft ? 'saved' : 'sent'}."
else
flash.now[:alert] = 'All email fields need to be filled out prior to sending/saving.'
render 'compose'
end
else
flash.now[:alert] = 'You do not have enough credits to send any more InMail to Game Changers.'
render 'compose'
end
ActivityLog.create(userid: current_user.id, points: 500, typeof: "message")
end
def allowed_send_mail?
unless !current_user.admin?
msg = "You are not authorized to access this page!"
show_error(msg)
end
end
def profile_complete
return true if current_user.mentor?
unless current_user.profile_complete?
flash[:alert] = t('errors.inbox.incomplete_profile')
redirect_to edit_user_registration_path
end
end
def message_params
params.require(:message).permit(:id, :to_name, :to_id, :subject, :body)
end
end
This is my relevant index.erb.html file.
<%= form_tag inbox_search_path, :method => 'get' do %>
<p>
<%= search_field_tag :Search, params[:search] %>
<%= submit_tag "Search", :name => nil %>
</p>
<% end %>
This is my relevant routes.rb file:
get 'inbox' => 'inbox#index', :as => 'inbox_index'
get 'inbox/show/:id' => 'inbox#show', :as => 'inbox_show'
get 'inbox/compose' => 'inbox#compose', :as => 'inbox_compose'
get 'inbox/compose/:id' => 'inbox#compose', :as => 'inbox_compose_to'
get 'inbox/edit/:id' => 'inbox#edit', :as => 'inbox_edit'
get 'inbox/move' => 'inbox#move', :as => 'inbox_move'
get 'inbox/reply' => 'inbox#reply', :as => 'inbox_reply'
get 'inbox/search' => 'inbox#search', :as => 'inbox_search'
post 'inbox/create' => 'inbox#create'
post 'inbox/bulk' => 'inbox#bulk'
There is no search method in this controller, the only search I see is a call to Inbox.search.
To debug this, start with the view where you actually do the "click". Is that click really supposed to trigger an action in your InboxController? If you think it should, why is there no action in that controller? If not, then the "click" was meant to go to another controller that actually would handle the search action, in which case you need to figure out why the "click" is trying to call a method in your InboxController rather than the desired controller. The problem could be something in your view or something in you routes, or you really should have that method in you InboxController, either way I suggest you try to figure out at least what should be happening and then post some more code stating what you think should be happening vs what is really happening.
Suggestions on how to improve this question are welcome
I added 3 things to the Devise user after generating it.
t.integer "role"
t.string "firstname"
t.string "lastname"
At User Signup these parameters are permitted and user is created correctly.
When a user tries to edit their account the "firstname" and "lastname" values can be changed fine but when a user tries to change their role on their /users/edit page, no error is given, flash says "account updated successfully" but the role value have not changed.
From /log/development.log showing all 3 parameters as unpermitted, if this really is the case I don't know why the other two can be updated.
Parameters: {"utf8"=>"✓", "authenticity_token"=>"LnVPFFJKV+RtnB21ZUGr4HF1siVcEuT/BRXaLVkch1nWQXiGRFVGhdWchlQSZ9A7mFgKX2njEjCbqR4CHp5hmQ==", "user"=>{"role"=>"worker", "firstname"=>"asdfDe Wet", "lastname"=>"Blomerus", "email"=>"dewet#blomerus.org", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", "current_password"=>"[FILTERED]"}, "commit"=>"Update"}
[1m[36mUser Load (0.8ms)[0m [1mSELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT 1[0m [["id", 6]]
[1m[35mUser Load (0.4ms)[0m SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 6]]
Unpermitted parameters: role, firstname, lastname
Redirected to http://localhost:3000/
Completed 302 Found in 84ms (ActiveRecord: 1.5ms)
/config/initializers/devise_permitted_parameters.rb
module DevisePermittedParameters
extend ActiveSupport::Concern
included do
before_filter :configure_permitted_parameters
end
protected
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) << [:firstname, :lastname, :role]
devise_parameter_sanitizer.for(:account_update) << [:firstname, :lastname, :role]
end
end
DeviseController.send :include, DevisePermittedParameters
Relevant parts of /app/controllers/users_controller.rb
def update
#user = User.find(params[:id])
if #user.update_attributes(secure_params)
redirect_to users_path, :notice => "User updated."
else
redirect_to users_path, :alert => "Unable to update user."
end
end
private
def secure_params
params.require(:user).permit(:role, :firstname, :lastname)
end
The update action never runs, I can completely comment it out and nothing changes.
This is what works for me with devise:
I change the users/registrations_controller.rb
class Users::RegistrationsController < Devise::RegistrationsController
before_action :configure_permitted_parameters, only: [:create]
before_filter :configure_account_update_params, only: [:update]
def create
super
end
# GET /resource/edit
def edit
super
end
# PUT /resource
def update
super
end
# DELETE /resource
def destroy
super
end
protected
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) do |u|
u.permit(:first_name, :last_name, :user_name, :email, :password, :password_confirmation, :avatar, :avatar_cache)
end
end
def configure_account_update_params
devise_parameter_sanitizer.for(:account_update)do |u|
u.permit(:first_name, :last_name, :user_name, :email, :password, :password_confirmation, :current_password, :avatar, :avatar_cache)
end
end
I don't define any update action in the users_controller.rb . It is not needed. Also, I don;t use any type of module that you are defining and it works fine.
Having major Rails issues currently. I'm creating a School-Dashboard app that takes an xref table called Enrollments that relates Courses and Students.
Any time I try to update a grade for an Enrollment, I constantly get this line
ActiveRecord::StatementInvalid: SQLite3::SQLException: no such column: UPDATE
"enrollments" SET "grade" = ?, "updated_at" = ? WHERE "enrollments"."" IS NULL
This line does not appear when I update attributes for Courses or Students. Only for the :grade attribute in Enrollment.
For some reason, it isn't being read properly, even though it is a legitimate attribute in my db for Enrollment (check out my schema).
I do all of my preliminary work in the rails sandbox.
Using ruby 2.1.1, Rails 4.1.0.rc1
I'd really love some help here.
Here are my corresponding models
class Student < ActiveRecord::Base
has_many :enrollments
has_many :courses, through: :enrollments
end
class Course < ActiveRecord::Base
has_many :enrollments
has_many :students, through: :enrollments
end
class Enrollment < ActiveRecord::Base
belongs_to :student
belongs_to :course
end
The controllers:
Students
class StudentsController < ApplicationController
def index
#students = Student.all
end
def new
#student = Student.new
end
def show
end
def update
#student.update_attributes(student_params) ? redirect_to #student : render 'edit'
end
def create
#student = Student.new(student_params)
#student.save ? redirect_to #student : render 'new'
end
def destroy
end
def edit
end
private
def student_params
params.require(:student).permit(:first_name, :last_name, :student_number, :email)
end
end
Courses
class CoursesController < ApplicationController
def index
#courses = Course.all
end
def new
#course = Course.new
end
def show
end
def update
#course.update_attributes(course_params) ? redirect_to #course : render 'edit'
end
def create
#course = Course.new(course_params)
#course.save ? redirect_to #course : render 'new'
end
def destroy
end
def edit
# code here
end
private
def course_params
params.require(:course).permit(:course_name, :course_number)
end
end
Enrollments
class EnrollmentsController < ApplicationController
attr_accessor :course_id, :student_id, :grade
def index
#enrollments = Enrollment.all
end
def new
#enrollment = Enrollment.new
end
def create
#enrollment = Enrollment.new(enrollment_params)
#enrollment.save ? redirect_to #enrollment : render 'new'
end
def update
#enrollment.update_attributes(enrollment_params) ? redirect_to #enrollment : render 'edit'
end
def show
end
def destroy
#enrollment.destroy
end
def edit
# code here
end
private
def enrollment_params
params.require(:enrollment).permit(:course_id, :student_id, :grade)
end
end
And finally my schema.rb
ActiveRecord::Schema.define(version: 20140417152720) do
create_table "courses", force: true do |t|
t.string "course_name"
t.integer "course_number"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "enrollments", id: false, force: true do |t|
t.integer "course_id", null: false
t.integer "student_id", null: false
t.decimal "grade", precision: 5, scale: 2
t.datetime "created_at"
t.datetime "updated_at"
end
# noinspection RailsParamDefResolve
add_index "enrollments", ["course_id", "student_id"], name: "index_enrollments_on_course_id_and_student_id"
# noinspection RailsParamDefResolve
add_index "enrollments", ["student_id", "course_id"], name: "index_enrollments_on_student_id_and_course_id"
create_table "students", force: true do |t|
t.string "first_name"
t.string "last_name"
t.string "email"
t.integer "student_number"
t.datetime "created_at"
t.datetime "updated_at"
end
end
Looks like I figured it out on my own!
So here's a bit of rails convention that needs to be addressed. The problem was with my database setup for 'Enrollments'. When I run the command
rails g migration CreateJoinTableEnrollments course student
Rails does too much work for me in my migration file (except for the table name and grade, I added that)
class CreateJoinTableEnrollments < ActiveRecord::Migration
def change
create_join_table :courses, :students, table_name: :enrollments, id: false, force: true do |t|
t.index [:course_id, :student_id], null: false
t.index [:student_id, :course_id], null :false
t.decimal :grade, precision: 5, scale: 2
t.timestamps
end
end
end
In reality, I didn't need any of that. In order to manipulate specific data in a row for Enrollments, there has to be an identifier for that row. With id: false, force: true that option got nullified. I also simplified things with the indexing. I just created regular old columns instead. Now my migration file looks like this.
class CreateJoinTableEnrollments < ActiveRecord::Migration
def change
create_table :enrollments do |t|
t.integer :course_id, null: false
t.integer :student_id, null: false
t.decimal :grade, precision: 5, scale: 2
t.timestamps
end
end
end
And with that, no issues! I've just been breaking my head over that for the past 2 days. Hope this helps anyone else who has this issue.