Reputation: 1322
I'm trying to implement the devise gem into my web app - everything with user login and registration is working, but when a user tries to actually leave a prediction (the only thing you need to be logged in for), I get this error message: undefined method `user=' for nil:NilClass. I can't seem to figure out what's causing this problem. Might anyone know?
_login_items.html.erb:
<ul>
<% if user_signed_in? %>
<li>
<%= link_to('Logout', destroy_user_session_path, :method => :delete) %>
</li>
<% else %>
<li>
<%= link_to('Login', new_user_session_path) %>
</li>
<% end %>
<% if user_signed_in? %>
<li>
<%= link_to('Edit registration', edit_user_registration_path) %>
</li>
<% else %>
<li>
<%= link_to('Register', new_user_registration_path) %>
</li>
<% end %>
</ul>
prediction model:
class Prediction < ActiveRecord::Base
belongs_to :student
belongs_to :user
end
user model:
class User < ActiveRecord::Base
has_many :predictions
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
end
predictions migration:
class CreatePredictions < ActiveRecord::Migration
def change
create_table :predictions do |t|
t.string :prediction
t.belongs_to :student, index: true
t.belongs_to :user
t.timestamps
end
end
end
user migration:
class DeviseCreateUsers < ActiveRecord::Migration
def change
create_table(:users) do |t|
## Database authenticatable
t.string :email, null: false, default: ""
t.string :encrypted_password, null: false, default: ""
## Recoverable
t.string :reset_password_token
t.datetime :reset_password_sent_at
## Rememberable
t.datetime :remember_created_at
## Trackable
t.integer :sign_in_count, default: 0, null: false
t.datetime :current_sign_in_at
t.datetime :last_sign_in_at
t.inet :current_sign_in_ip
t.inet :last_sign_in_ip
## Confirmable
# t.string :confirmation_token
# t.datetime :confirmed_at
# t.datetime :confirmation_sent_at
# t.string :unconfirmed_email # Only if using reconfirmable
## Lockable
# t.integer :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts
# t.string :unlock_token # Only if unlock strategy is :email or :both
# t.datetime :locked_at
t.timestamps
end
add_index :users, :email, unique: true
add_index :users, :reset_password_token, unique: true
# add_index :users, :confirmation_token, unique: true
# add_index :users, :unlock_token, unique: true
end
end
predictions controller:
class PredictionsController <ApplicationController
def create
@prediction.user = current_user
Prediction.create(prediction_params)
redirect_to :back
end
def new
@prediction = Prediction.new(student_id: params[:student_id])
end
def destroy
Prediction.find(params[:id]).destroy
redirect_to :back
end
private
def prediction_params
params.require(:prediction).permit(:prediction) #, :student_id
end
end
Upvotes: 1
Views: 306
Reputation: 13521
The problem is in your PredictionsController. You have to create the prediction and assign it to a variable first. Change your create action to this:
def create
@prediction = Prediction.create(prediction_params)
@prediction.user = current_user
redirect_to :back
end
You were trying to assign a user to a non existing prediction. This correction creates the prediction first then assigns the user to it.
Edit: I noticed one other problem: Your prediction_params
method is incorrect. The arguments you pass to the permit
method must be the attributes of your prediction model which you want to mass assign. The :prediction
key in the params is the one you want to require but within that nested hash you want to permit attributes of the prediction
model. So, hypothetically, if your prediction model has :name
, :value
and :student_id
attributes, your prediction_params
method should look like this:
def prediction_params
params.require(:prediction).permit(:name, :value, :student_id)
end
This will work with a params
hash that looks like:
{
prediction: {
name: 'something',
value: 'stuff',
student_id: 1
}
}
Upvotes: 1