为关联模型创建新对象

时间:2017-05-31 04:02:52

标签: ruby-on-rails ruby ajax ruby-on-rails-5

所以我已经有一段时间了,尝试过一系列不同的方法。基本上我有一个过度拱形的property模型和一个相关的deed模型。从properties#show view开始,我显示了所有关联的deeds。我的property view中有一个按钮,它显示一个模态(使用AJAX)来创建与所述模型关联的deed。所有步骤都有效(甚至可以在属性视图中使用AJAX进行编辑和更新),除非在尝试保存new deed时收到错误消息:

This form contains 1 error. Property must exist

我试过以不同的方式通过@properties.id,我似乎无法得到它。我将列出我拥有的所有相关信息,如果需要更多信息,请告诉我。

属性模型

class Property < ApplicationRecord
  has_many :deeds, dependent: :destroy
  accepts_nested_attributes_for :deeds
end

契约模型

class Deed < ApplicationRecord 
  belongs_to :property
  accepts_nested_attributes_for :property
end

契约控制器(包括编辑和更新操作)

def new
  @deeds = Deed.new
  @deeds.build_property
  respond_to do |format|
    format.html { render 'new'}
    format.js
  end
end

def create
  @properties = Property.find(params[:deed][:property_id])
  @deeds = @properties.deeds.new(deed_params)
  if @deeds.save
    flash[:success] = "Deed created successfully!"
    respond_to do |format|
      format.html { redirect_to deeds_path }
      format.js
    end
  else
    render 'new'
  end
end

def edit
  @deeds = Deed.find(params[:id])
  respond_to do |format|
    format.html { @deeds.save }
    format.js
  end
end

def update
  @deeds = Deed.find(params[:id])
  @properties = Property.find(@deeds.property.id)
  @deeds.update_attributes(deed_params)
  respond_to do |format|
    format.html { redirect_to deeds_path }
    format.js
  end
end

private

 def deed_params
   params.require(:deed).permit(:property_id, :deed_number, :deed_context, :consideration, :recorded_date, :grantor, :grantee, :trustee)
 end
来自new deeds视图

properties#show链接

<%= link_to fa_icon("plus", text: "Add Deed"), new_property_deed_path(@properties.id), remote: true, class: "btn btn-primary btn-large btn-ouline pull-right", locals: { property_id: @properties } %>

new.js.erb

$('#deeds-modal').modal("show");
$('#deeds-modal').html('<%= j render partial: "deeds/deeds_modal", locals: { property_id: @properties } %>');

_deeds_modal.html.erb partial表格

<div class="modal-body">
  <%= bootstrap_form_for(@deeds, layout: :horizontal, remote: true) do |f| %>
      <%= render 'shared/error_messages', object: f.object %>

      <%= f.hidden_field :property_id, value: property_id %>

      <%= f.text_field :deed_number, class: 'form-control' %>

      <%= f.text_field :deed_context, class: 'form-control' %>

      <%= f.text_field :consideration, class: 'form-control' %>

      <%= f.text_field :recorded_date,     class: 'form-control' %>

      <%= f.text_field :grantor,    class: 'form-control' %>

      <%= f.text_field :grantee,  class: 'form-control' %>

      <%= f.text_field :trustee,  class: 'form-control' %>

      <%= f.form_group do %>
          <%= f.submit "Save", class: "btn btn-primary" %>
      <% end %>

  <% end %>
</div>

服务器响应deeds_modal form POST

Started GET "/properties/99/deeds/new" for 127.0.0.1 at 2017-05-30 
23:24:48 -0400
Processing by DeedsController#new as JS
  Parameters: {"property_id"=>"99"}
  Rendering deeds/new.js.erb
  Rendered shared/_error_messages.html.erb (0.4ms)
  Rendered deeds/_deeds_modal.html.erb (5.6ms)
  Rendered deeds/new.js.erb (7.3ms)
Completed 200 OK in 14ms (Views: 10.6ms | ActiveRecord: 0.0ms)


Started POST "/deeds" for 127.0.0.1 at 2017-05-30 23:24:55 -0400
Processing by DeedsController#create as JS
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"eaj9K...==", "deed"=>{"property_id"=>"", "deed_number"=>"69696969", "deed_context"=>"Bagel slaps", "consideration"=>"Considered", "recorded_date"=>"2017-05-31", "grantor"=>"", "grantee"=>"NipLips", "trustee"=>""}, "commit"=>"Save"}
   (0.1ms)  BEGIN
   (0.1ms)  ROLLBACK
  Rendering deeds/new.js.erb
  Rendered shared/_error_messages.html.erb (0.7ms)
  Rendered deeds/_deeds_modal.html.erb (12.1ms)
  Rendered deeds/new.js.erb (20.4ms)
Completed 200 OK in 32ms (Views: 30.6ms | ActiveRecord: 0.2ms)

因为你可以看到我试图通过new link - &gt;中的局部变量。 new.js.erb - &gt; deeds modal form但我似乎无法将property_id拉入new deeds object

这是我正在尝试做什么的正确方法,还是我错过了什么?希望这不是一个阅读太长,我提供了足够的信息...大声笑。

*在撰写这篇文章后,我点击了一些类似的问题&#39;在SO上,这是我获得@properties = Property.find(params[:deed][:property_id])行的地方,但我在提交时仍然得到ActiveRecord::RecordNotFound (Couldn't find Property with 'id'=):。另外,感谢任何花时间阅读此内容的人。

rails routes更新(仅包括相关路线)

deeds GET    /deeds(.:format)                                      deeds#index
                   POST   /deeds(.:format)                                      deeds#create
          new_deed GET    /deeds/new(.:format)                                  deeds#new
         edit_deed GET    /deeds/:id/edit(.:format)                             deeds#edit
              deed GET    /deeds/:id(.:format)                                  deeds#show
                   PATCH  /deeds/:id(.:format)                                  deeds#update
                   PUT    /deeds/:id(.:format)                                  deeds#update
                   DELETE /deeds/:id(.:format)                                  deeds#destroy
...
property_deeds GET    /properties/:property_id/deeds(.:format)              deeds#index
                   POST   /properties/:property_id/deeds(.:format)              deeds#create
 new_property_deed GET    /properties/:property_id/deeds/new(.:format)          deeds#new
edit_property_deed GET    /properties/:property_id/deeds/:id/edit(.:format)     deeds#edit
     property_deed GET    /properties/:property_id/deeds/:id(.:format)          deeds#show
                   PATCH  /properties/:property_id/deeds/:id(.:format)          deeds#update
                   PUT    /properties/:property_id/deeds/:id(.:format)          deeds#update
                   DELETE /properties/:property_id/deeds/:id(.:format)          deeds#destroy

2 个答案:

答案 0 :(得分:2)

这应该是你new行动

def new
  @deeds = Deed.new
  @deeds.build_property
  @properties = Property.find_by_id(params[:property_id]) # add this line
  respond_to do |format|
    format.html { render 'new'}
    format.js
  end
end

<强>更新

如果您未在其他任何地方使用associated媒体资源,则无需传递locals,我也不建议使用hidden_field,因为它可以轻松修改,也可以你可以做..

def new
  @deeds = Property.find_by_id(params[:property_id]).deeds.new # add this line
  @deeds.build_property
  respond_to do |format|
    format.html { render 'new'}
    format.js
  end
end

答案 1 :(得分:1)

由于错误显示为'0',因此,您的目的是打印Property must exist以获取新记录,但出于某种原因,这种情况并未发生。

由于该值直接来自您的property_id以创建新的“契约”,然后必须在其上设置,您可以执行此操作,但是您不会检查它是否正在打印某些内容,并且由于契约和属性之间的关系,得到你不允许的form_for值。

发送表单时,您可以看到值为空:

nil

如何定义新记录必须包含哪个"deed"=>{"property_id"=>""} ?您可以在property_id方法中创建变量,并将对象设置为在new内打印,它会为您提供继续创建新记录的值。

当您向新方法发出请求时,您会通过参数传递form_for的值:

property_id

所以我想你可以用它代替设置一个尚未初始化的局部变量,也许你可以试试:

Processing by DeedsController#new as JS
Parameters: {"property_id"=>"99"}