2

In my Rails 4 Controller action, I'm passing the following params:

{"user"=>{"email"=>"", "password"=>"[FILTERED]", "profile"=>{"birthday"=>nil, "gender"=>nil, "location"=>"", "name"=>""}}}

Now from those params I'm hoping to create two objects: User and its Profile.

I've tried iterations of the following code but can't get passed strong_params issues:

def create
  user = User.new(user_params)
  profile = user.build_profile(profile_params)

  ...
end

  private

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

    def profile_params
      params[:user].require(:profile).permit(:name, :birthday, :gender, :location)
    end

Since the code above throws an Unpermitted parameters: profile error, I'm wondering if the profile_params method is even ever getting hit. It almost feels like I need to require profile in user_params and handle that. I've tried that as well, changing my strong_params methods to:

def create
  user = User.new(user_params)
  profile_params = user_params.delete(:profile)
  profile = user.build_profile(profile_params)

  ...
end

private

  def user_params
    params.require(:user).permit(:email, :password, profile: [:name, :birthday, :gender, :location])
  end

But I get ActiveRecord::AssociationTypeMismatch - Profile(#70250830079180) expected, got ActionController::Parameters(#70250792292140):

Can anyone shed some light on this?

2 Answers 2

4

This is without a doubt a time when nested parameters should be used.

You should make the following changes:

model:

class User < ActiveRecord::Base
    has_one :profile
    accepts_nested_attributes_for :profiles,  :allow_destroy => true 
end

class Profile < ActiveRecord::Base
    belongs_to :user
end

Users controller:

def user_params
    params.require(:user).permit(:email, :password, profile_attributes: [:name, :birthday, :gender, :location])
end  #you might need to make it profiles_attributes (plural)

In your form view, make sure to use the fields_for method for your profiles attributes.

Sign up to request clarification or add additional context in comments.

1 Comment

Definitely valid about using nested attributes. Thanks for the reminder there.
3

Try this:

user = User.new(user_params.except(:profile))
profile = user.build_profile(user_params[:profile])

You could also use Rails' nested attributes. In that case, the profile params would be nested within the key :profile_attributes.

1 Comment

Ah, didn't know about except. Thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.