Creating two objects in Rails 4 controller with strong_params

别来无恙 提交于 2020-01-04 11:40:11

问题


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?


回答1:


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.




回答2:


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.



来源:https://stackoverflow.com/questions/21222015/creating-two-objects-in-rails-4-controller-with-strong-params

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!