Rails / ActiveRecord - 关联不保存

时间:2017-02-02 15:14:46

标签: ruby-on-rails activerecord associations nested-attributes

我无法获取我的CheckIn记录以进行保存,因为相关的租约不会保存。

我有三个关联模型:

class Property < ApplicationRecord
  has_many :tenancies
end

class Tenancy < ApplicationRecord
  belongs_to :property
  has_many :check_ins
end

class CheckIn < ApplicationRecord
  belongs_to :tenancy
  accepts_nested_attributes_for :tenancy
end

我希望CheckIn新操作同时创建CheckIn和相关的租期:

def new
  @check_in = CheckIn.new
  @check_in.build_tenancy.property_id = params[:property_id]
end

我必须包含property_id部分,否则租约不会保存。

check_ins / new.html.erb中的表单:

<%= form_for @check_in, url: property_check_ins_path do |f| %>
  <%= f.label :date_time %>
  <%= f.datetime_select :date_time, {minute_step: 15} %>

  <%= f.label :tenancy %>
  <%= f.fields_for :tenancy do |i| %>
    <%= i.date_select :start_date %>
  <% end %>

  <%= f.submit "Create Check In" %>
<% end %>

我已经在CheckInsController的强参数中添加了租赁属性:

def check_in_params
  params.require(:check_in).permit(:tenancy_id, :date_time, tenancy_attributes: [:start_date])
end

值得注意的是check_ins路由嵌套在属性中:

resources :properties do
  resources :check_ins, only: [:new, :create]
end

所以问题是,当我在CheckInsController中进行创建操作时,我构建的租赁已经消失了。我不确定每个记录应该如何以及何时被保存,而我想要实现的轻微复杂性使得很难找到相关的帮助,所以任何想法?

我使用Rails 5。

2 个答案:

答案 0 :(得分:0)

问题是附属于租约的财产被遗忘了。我从新操作中删除了属性附件:

def new
  @check_in = CheckIn.new
  @check_in.build_tenancy
end

为表单添加了property_id的隐藏字段(以及向强参数添加:property_id):

<%= f.fields_for :tenancy do |i| %>
  <%= i.date_select :start_date %>
  <%= i.hidden_field :property_id, value: params[:property_id] %>
<% end %>

在保存支票之前,将租约保存在CheckIn创建操作中:

def create
  @check_in = CheckIn.new(check_in_params)
  @check_in.tenancy.save

  if @check_in.save
    redirect_to property_check_in_path(@check_in.tenancy.property.id, @check_in)
  else
    render :new
  end
end

如果有人能在这个解决方案中找到漏洞或提供更好的解决方案,我当然会感兴趣。

答案 1 :(得分:0)

使用嵌套资源(check_ins取决于属性)可以创建名称空间路由。 form_for helper rails guides - form helpers)构建表单时,还需要一个Property引用。

我试着通过一个例子更好地解释我:

<强>#checks_controller.rb

def new
  @property = Property.new
  @check_in = @property.build_check_ins
  @check_in.build_tenancy
end

<强>#check_ins / new.html.erb

<%= form_for [@property, @check_in], url: property_check_ins_path do |f| %>
  <%= f.label :date_time %>
  <%= f.datetime_select :date_time, {minute_step: 15} %>

  <%= f.label :tenancy %>
  <%= f.fields_for :tenancy do |i| %>
    <%= i.date_select :start_date %>
  <% end %>

  <%= f.submit "Create Check In" %>
<% end %>

我没有尝试过这段代码,但我希望这至少可以帮助您解决问题。