2

I followed the rails cast tutorial for user authentication/registration/login which apparently has an outdated method of using the gem protected attributes. I found that it's necessary to switch to strong parameters and did so by following this method.

I had to delete the attr_accessible code from my user.rb model (commented out below) and was wondering if there's anything else I should do instead of just defining user params within the controller. Should there be attr_accessors for the user's fields (email, password, location) now that I don't have the attr_accessible or is this unnecessary? I'm new to rails and do not fully understand the proper necessities for user authentication.

user.rb

class User < ActiveRecord::Base
  #attr_accessible :email, :password, :password_confirmation, :location

  attr_accessor :password, :location
  before_save :encrypt_password

  validates_confirmation_of :password
  validates_presence_of :password, :on => :create
  validates_presence_of :email
  validates_uniqueness_of :email

  def self.authenticate(email, password)
    user = find_by_email(email)
    if user && user.password_hash == BCrypt::Engine.hash_secret(password, user.password_salt)
      user
    else
      nil
    end
  end

  def encrypt_password
    if password.present?
      self.password_salt = BCrypt::Engine.generate_salt
      self.password_hash = BCrypt::Engine.hash_secret(password, password_salt)
    end
  end
end 

user_controller.rb

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

  #add thing from https://stackoverflow.com/a/19130224/2739431
  private
    def user_params
      params.require(:user).permit(:email, :password, :password_confirmation, :location)
    end

end
Community
  • 1
  • 1
parameter
  • 894
  • 2
  • 18
  • 35

2 Answers2

1

The answer is relatively simple.

Remember that statement when you first started learning Ruby: "In Ruby, everything is an object". Objects have methods, and to access an objects property you need an accessor method.

The attr_accessor is a Ruby method that generates accessor methods for a given instance variable (check attr_reader and attr_writer).
So your question actually is whether you need to access those properties, outside the Model.

And I think this answeres your question.

Important note: attr_accessible is not a Ruby method. It's a Rails method that allows you to pass in values to Models for a mass assignment: new(attrs) or update_attributes(attrs).

Itay Grudev
  • 7,055
  • 4
  • 54
  • 86
  • "So your question actually is whether you need to access those properties, outside the Model." But ActiveRecord generates accessors automatically for database fields, so "whether you need to access those properties outside the Model" is not really a question, because the accessors are already there. – Rafał Cieślak Mar 30 '14 at 18:10
  • You are correct. But you did said database fields and they might not be fields, rather then instance variables. Indeed there is difference, but I tried to be more generic so people in future don't confuse the two things. – Itay Grudev Mar 30 '14 at 18:13
1

Should there be attr_accessors for the user's fields (email, password, location) now that I don't have the attr_accessible or is this unnecessary?

It's unnecessary. ActiveRecord automatically creates writers and readers for model fields – that's why you can use methods like user.email and user.email = outside of User class.

attr_accessor :password, :location – I guess these are database fields, right? You can remove this line, too.

Rafał Cieślak
  • 972
  • 1
  • 8
  • 25
  • when I remove that line I get an error saying that it can't find the parameter "password" when I attempt to register a new user. – parameter Mar 30 '14 at 18:18
  • Okay, so everything's fine, looks like `password` and `location` operate on instance variables, not database fields. – Rafał Cieślak Mar 30 '14 at 18:23
  • and oddly enough when I add one for :email then it won't let me log into the account once I create it. I'm guessing because it interferes with the database field for email. – parameter Mar 30 '14 at 18:36