【问题标题】:Creating new object for associated model为关联模型创建新对象
【发布时间】:2017-05-31 04:02:51
【问题描述】:

所以我已经有一段时间了,并尝试了很多不同的方法。本质上,我有一个包罗万象的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

Deeds Controller(包括编辑和更新操作)

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 -> new.js.erb -> deeds modal form 传递局部变量,但我似乎无法将 property_id 拉入 new deeds object .

对于我正在尝试做的事情,这甚至是正确的方法还是我只是错过了一些东西?希望这不是太长的阅读时间,并且我提供了足够的信息......哈哈。

*在写这篇文章时,我点击了一些关于 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

【问题讨论】:

  • hidden_field中的property_id 怎么设置,能查出是不是nil吗?
  • 老实说,我不完全确定在这种情况下如何检查,我对 Rails 还是有点陌生​​,我认为这会涉及到某个地方的 .nil? 呼叫,但我我不能 100% 确定我会在这个过程中把它放在哪里。但是,我认为我是通过将局部变量传递给渲染调用来设置的,所以也许这就是我所缺少的?
  • 按部分进行,检查表单以及检查源代码的隐藏输入的值是什么。
  • 这里可以清楚的看到Parameters: {"utf8"=&gt;"✓", "authenticity_token"=&gt;"eaj9K...==", "deed"=&gt;{"property_id"=&gt;"",...是nil,需要在new中设置。请分享您的路线rake routes
  • 试试&lt;%= f.hidden_field :property_id, value: @deeds.property_id %&gt;

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


【解决方案1】:

这应该是你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

【讨论】:

  • 太棒了! @properties = Property.find_by_id(params[:property_id]) 绝对是我在 new 操作中需要的那个。一旦与上面塞巴斯蒂安的答案相结合,这非常有效!
  • 很高兴它有效,请接受答案,因为它有帮助.. :)
【解决方案2】:

正如错误所说的 Property must exist,因此,您的意图是打印 property_id 以获取新记录,但由于某种原因,这没有发生。

由于该值直接来自您的form_for 以创建新的“契约”,因此必须在其上设置 in,您执行此操作,但您不检查它是否正在打印某些内容,它得到了您一个 nil 值,由于契约和属性之间的关系而不允许使用。

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

"deed"=>{"property_id"=>""}

你如何定义新记录必须有哪个property_id?您可以在 new 方法中创建一个变量,并在您的 form_for 中设置一个要打印的对象,它会为您提供一个值以继续处理新记录。

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

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

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

<%= f.hidden_field :property_id, value: params[:property_id] %>

【讨论】:

  • 感谢您的洞察!一旦我通过value: params[:property_id] 并在下面添加@properties = ... 行,一切正常!
  • @cdouble.bhuck 好吧,你必须做任何一个而不是两者都做......如果你使用params[:propery_id]你不需要在本地传递@properties..
  • 很高兴能提供帮助,只是您可以跳过在控制器中创建变量以将其发送到视图,因为与您在 new 视图中收到的值“params[:property_id]”相同。跨度>
  • 啊,我明白了,它确实可以在控制器中没有 @properties 变量的情况下工作。但是,如果我不通过 params[:property_id],它不适用于 only 控制器中的 @properties。我在new modal 页面上呈现了其他从:property_id 提取的东西现在可以工作,那么两者都可以吗?
  • 如果你想使用@properties那么,这应该是你对本地人的看法locals: { property_id: @properties.id }f.hidden_field :property_id, value: property_id,但是,如果你不使用它,我建议不使用@properties在其他任何地方,它都会为您节省一个 db fetch else checkout updated answer
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-04-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-25
  • 1970-01-01
相关资源
最近更新 更多