0

I'm following Micheal Hartl's Ruby on Rails Tutorial Book.I'm testing validation for the presence of name and email in the sample_app.In rails console, I'm running

user = User.new(:email => "user@example.com")

to test an absent name value but I'm getting in return;

attr_accessible is extracted out of Rails into a gem.
Please use new recommended protection model for params(strong_parameters)
or add 'protected_attributes' to your Gemfile.

My user.rb is,

class User < ActiveRecord::Base

attr_accessible :name, :email

validates :name, :presence => true
validates :email, :presence => true
end

Because I'm not sure how to use strong_parameters I added protected_attributes to my Gemfile like so,

source 'https://rubygems.org'

gem 'protected_attributes'

# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '4.0.2'

# Use sqlite3 as the database for Active Record
gem 'sqlite3'

# Use SCSS for stylesheets
gem 'sass-rails', '~> 4.0.0'

gem 'uglifier', '>= 1.3.0'


gem 'coffee-rails', '~> 4.0.0'


 gem 'therubyracer', platforms: :ruby
gem 'jquery-rails'
gem 'turbolinks'
gem 'jbuilder', '~> 1.2'

group :doc do
 # bundle exec rake doc:rails generates the API under doc/api.
 gem 'sdoc', require: false
end
group :test do
gem 'rspec'
end

group :development do
gem 'rspec-rails'
end


# Use ActiveModel has_secure_password
# gem 'bcrypt-ruby', '~> 3.1.2'

# Use unicorn as the app server
# gem 'unicorn'

# Use Capistrano for deployment
# gem 'capistrano', group: :development

# Use debugger
# gem 'debugger', group: [:development, :test]

How can I get my validation to work?

yaboiduke
  • 652
  • 7
  • 20

3 Answers3

3

Micheal Hartl's Ruby on Rails Tutorial Book is using rails3 version. But the project you have made is in rails4.

Rails4 uses strong parameters. If you want to go with rails3 syntax add the "protected_attributes" gem and do bundle install. What I would suggest is to use the new syntax of rails4 for the same. Instead of using attr_accessible in User model, make a private method in the users_controller.

private

def user_params
  params.require(:user).permit(:name, :email)
end
Siddhant
  • 293
  • 1
  • 3
  • 8
1

in Rails 4 you need to remove attr_accessible :name, :email from your User model.

Instead you need to have strong parameters in you User controller:

    def user_params
      params.require(:user).permit(:name, :email, :password,
                                   :password_confirmation)
    end

Take a look at Rails Tutorial (Rails version 4) code samples for User controller and User model

More info on strong parameters

jyrkim
  • 2,849
  • 1
  • 24
  • 33
0

The other two answers here are what you need, but to add some information about strong_params, I wanted to outline why they're being used:

It provides an interface for protecting attributes from end-user assignment. This makes Action Controller parameters forbidden to be used in Active Model mass assignment until they have been whitelisted

Mass Assignment (as described so well here) is bad because it just means you can send any param to your controller, and it will use that data with the model without any prior validation (potentially allowing you to edit any data on the system)

To combat this problem, Rails 3 introduced attr_accessible to ensure only certain parameters are passed to the db. However, to make this even more secure, Rails 4 adopted strong_params to assign params at controller level

Essentially, you have to replace your attr_accessible with:

#app/controllers/users_controller.rb
def new
    @user = User.new #-> creates new ActiveRecord object
end

def create
    @user = User.new(user_params)
end

private

def user_params
    params.require(:user).permit(:your, :params)
end

PS also remove protected_attributes from your GemFile - you'll receive mass assignment errors :)

Richard Peck
  • 76,116
  • 9
  • 93
  • 147