Reputation: 11
That is the error im getting:
undefined method `attr_accessible' for #
after following a tutorial, my code is:
User.rb:
class User < ActiveRecord::Base
attr_accessible :email, :password, :password_confirmation
attr_accessor :password
before_save :encrypt_password
validates_confirmation_of :password
validates_presence_of :password, :on => :create
validates_presence_of :email
validates_uniqueness_of :email
users_conroller.rb:
class UsersController < ApplicationController
def new
@user = User.new
end
def create
@user = User.new(params[:user])
if @user.save
redirect_to root_url, :notice => "Signed up!"
else
render "new"
end
end
end
Help please! :( I read somewhere to change one of the js coffee files from coffee to just js and put a script in to allow this to work but it didn’t work for me
Upvotes: 0
Views: 565
Reputation: 347
attr_accessible is depricated in rails 4. please use user_params instead of attr_accessible. In User.rb
# no attr_accessible
In users_controller.rb
def create
@user = User.new user_params
@user.save
end
at the end
private
def user_params
params.require(:user).permit(:email, :password, :password_confirmation)
end
Hope this will help!!
Upvotes: 1
Reputation: 76784
MVC
To further BroiState
's amazing answer, you need to appreciate how Rails works as a framework - MVC:
MVC is one of the core aspects of Rails - it's how your data is processed & shown on the screen. The problem for many people is they don't realize the value of this system, and consequently don't realize how to get Rails to work as they require.
When you call data from your system, you're basically using the Model
aspect of the framework - the ability to call the data. The problem is that since Rails 3 & Rails 4 handle this differently, you're receiving the error as you're trying to access a function / method which simply doesn't exist.
--
Rails
In the sense of Rails, you have to appreciate that every time you call your data from the model, it will do so by compiling the relative attributes from the database.
Although you can access as much data as you need, Rails has some stringent methods to prevent mass assignment -- the ability for someone to populate attributes without being part of your application's flow.
The way to do this is to "white list" different attributes. Rails 3 did this with attr_accessible
, whilst Rails 4 adopted the strong_params
pattern:
With this plugin Action Controller parameters are forbidden to be used in Active Model mass assignments until they have been whitelisted. This means you'll have to make a conscious choice about which attributes to allow for mass updating and thus prevent accidentally exposing that which shouldn't be exposed.
The big difference here being that in Rails 4, you can access all the attributes you need from your model (the white listing is done when you submit data); whilst in Rails 3, you can only define the attributes accessed with the attr_accessible
directive.
Simply, here's what you have to do:
#app/models/user.rb
class User < ActiveRecord::Base
# NO attr_accessible
end
#app/controllers/users_controller.rb
class UsersController < ApplicationController
def new
@user = User.new
end
def create
@user = User.new user_params
@user.save
end
private
def user_params
params.require(:user).permit(:x, :y, :z)
end
end
Upvotes: 1
Reputation: 44715
This method is not defined in rails 4. Remove it from your models and update your controller so it reads like:
class UsersController < ApplicationController
def new
@user = User.new
end
def create
@user = User.new(user_params)
if @user.save
redirect_to root_url, :notice => "Signed up!"
else
render "new"
end
end
private
def user_params
params.require(:user).allow(:email, :password, :password_confirmation)
end
end
attr_accessible
is a method used in rails 3 to limit an access to certain params. Reason behind it was, that most controller 'create' or 'update' actions looks like:
@model.assign_attributes(params[:model])
Since params has been sent by the user, it might contain anything, including the fields we definitively don't want them to be able to change (like admin: true
).
Rails 3 solved that by saying, that only the attributes marked with attr_accessible
can be mass assigned, i.e. if a user tries to pass an extra param :admin
it will be rejected by assign_attributes
method (which is used internally in new
, create
etc.).
Now, this was not the best idea - there are certain situations when we want them to be able to set some params depending on the context, so for example if user creating the record is in fact an admin he can nominate another user to be admin. Hence, this security logic has been moved from the model to the controller and is known as strong attributes. You can see it uses in the solution at the top (user_params
method). This way is much more secure and harder to be misused.
Upvotes: 3