1

I'm new to Ruby/RoR and so far things have been going well, but I am having issues with updating the database from a form field (every field saves except the birthday field). I assume there is a minor implementation issue here but I'm having trouble working it out.

Form:

    <%= f.label :birthday %>
    <%= f.date_select :birthday, {order: [:month, :day, :year], prompt: { day: 'Select day', month: 'Select month', year: 'Select year' }, start_year: Date.today.year - 118, end_year: Date.today.year}, class: 'form-control' %>

User model:

    def update 
      @user = User.find(params[:id])
      if @user.update_attributes(user_params) 
        flash[:success] = "Profile updated"
        redirect_to @user
      else 
        render 'edit'
      end
    end

    def user_params
      unless logged_in?
        params.require(:user).permit(:first_name, :last_name, :email, :usertype, :password,:password_confirmation)
      else 
        params.require(:user).permit(:first_name, :last_name, :email, :password, :password_confirmation, :street, :city, :state, :zipcode,  :phone_number, :birthday, :month, :day, :year)
      end
    end

Database migration for field

    add_column :users, :birthday, :date
    add_column :users, :month, :date
    add_column :users, :day, :date
    add_column :users, :year, :date
kiddorails
  • 12,961
  • 2
  • 32
  • 41
MA1
  • 33
  • 6
  • do you have some pre-processing (before_save or before_create etc) in place in model? – kiddorails Jun 21 '18 at 18:01
  • Did you test whether the `else` block in `user_params` is firing? – possiblyLethal Jun 21 '18 at 18:06
  • What do you see if you print out the params at the top of the update method? – akowalz Jun 21 '18 at 18:40
  • I had :birthday included in `attr_accessor :remember_token, :activation_token, :reset_token` and once I removed that it seems to save - can someone provide context as to why that was an issue? Is it just because the model was pulling nil from the database and setting that equal to :birthday before updating user_params (aka :birthday from the form was overrode by a nil value)? – MA1 Jun 21 '18 at 18:49
  • @MA1 added an answer to explain that in detail. – kiddorails Jun 21 '18 at 19:07

1 Answers1

1

When you have attr_accessor for a field, it creates the virtual attributes which can be instantiated in context of Ruby object but does not map to the field of database.

In your case, since you have the database field birthday and you made the virtual attribute with same name, in update call, that attribute remained assigned to virtual attribute and not to the database field generated by ActiveRecord. Hence, your object wasn't saved.

attr_accessor in rails code is usually used when you do not have a corresponding field in database, but want to have attributes on object, say 'first_nameandlast_name, where database hasfull_name`.

Also, in context of Rails, attr_accessor is different from attr_accessible. Latter is often used to whitelist parameters for mass-assignment of attributes; it is replaced by Strong-parameters in newer version of Rails (which you are using)

Hope it helps :)

Edit : was searching if such question was asked around. Found this and think this will also be helpful to you - https://stackoverflow.com/a/4735726/1376448

kiddorails
  • 12,961
  • 2
  • 32
  • 41