在子create方法中创建父对象

时间:2015-08-20 00:54:39

标签: ruby-on-rails activerecord strong-parameters

关于SO有很多相关的问题。我经历了所有这些,但仍然困扰着我的情况。

我有两个模型UserBooking

#model/user.rb
has_many :bookings

#modle/booking.rb
belongs_to :user

我想同时创建bookinguser。如果用户已存在,只需将新预订添加到现有用户即可。

我创建booking的表单:

<%= simple_form_for :booking, url: bookings_path, :method => :post, do |f| %>
<%= f.fields_for :user, do |ff| %>
  <%= ff.input_field :first_name %>
  <%= ff.input_field :last_name %>
  <%= ff.input_field :email %>
  <%= ff.input_field :phone %>
<% end %>
...
<% end %>

booking控制器

#control/bookings_controller.rb
def create
  @user = User.find_by(:email => booking_params[:user][:email])
  if @user == nil
    @user = User.new(booking_params[:user])
    @user.username = User.autousername(@user)
    @user.password = Devise.firendly_token(8)
  else
    @user.update(booking_params[:user])
  end
  @user.save
  b_params = booking_params
  b_params.delete("user")
  @booking = Booking.new(b_params)
  @booking.user_id = @user.id
  @booking.save
...
end

def booking_params
  params.require(:booking).permit(:status, :house_id, :check_in, :check_out, :adult_guest, :children_guest, :temp_profit,
  :note, :check_in_note, :user => [:first_name, :last_name, :email, :phone])
end

我没有使用nested_attributes因为我想自己生成用户名和密码而不是使用表单收集它们。

我得到的是ActiveRecord::AssociationTypeMismatch in BookingsController#create User(#70121505047640) expected, got ActionController::Parameters(#70121556154400)

大多数与SO相关的问题都想在父控制器下创建子对象。就我而言,它已经逆转了。

更新

在尝试了一切可能的方法之后,我发现CanCanCan load_and_authorize_resource似乎是麻烦制造者。如果我在bookings_controller中注释掉它,一切正常。有人可以告诉我为什么吗?

解决方案

最后,我找到了原因。我在load_and_authorize_resource中使用了CanCanCan booking_controller。为了在其下创建嵌套的user实例,我必须加载user个资源。只需添加load_and_authorize_resource :user即可解决问题!

感谢所有答案。希望这能帮助有同样问题的人。

1 个答案:

答案 0 :(得分:0)

当您尝试执行@booking.save时,可能会发生这种情况。因为你有一个用户参数,它会尝试使用user =来设置它。在这种情况下,user =将应用params对象。

尝试在创建预订时从booking_params中删除用户参数。

b_params.delete(:user)

b_params[:user] = @user