从Rails 4开始我现在用一种常见的CRUD模式进行斗争。找到了一些资源但却得不到它。
让我们假设一个产品模型,一个供应商模型以及丰富的多对价格关联。许多供应商以不同的价格出售给定的产品。每个供应商都销售许多产品。丰富的多对多联合模型的名称是" costprices"。最终会出现以下三种模式。
class Product < ActiveRecord::Base
has_many :costprices
has_many :suppliers, through: :costprices
end
class Supplier < ActiveRecord::Base
has_many :costprices
has_many :products, through: :costprices
end
class Costprice < ActiveRecord::Base
belongs_to :product
belongs_to :supplier
end
供应商提供数百或数千种产品。产品由一个或一些(两个,三个,四个)供应商提供。对我来说,自然的方式似乎包括一个&#34;添加供应商的成本价格&#34;某些产品形式的功能,或者像我在这里一样,到产品展示页面。这个页面看起来像这样:
<p>
<strong>Name:</strong>
<%= @product.name %>
</p>
<%= link_to 'Edit', edit_product_path(@product) %> |
<%= link_to 'Back', products_path %>
<!-- List all suppiers offering this product -->
<table>
<% @product.costprices.each do |cp| %>
<tr>
<td>
<%= link_to edit_product_costprice_path(cp, @product) do %>
EDIT
<% end %>
</td>
<td>
<%= link_to product_costprice_path(cp, @product) do %>
SHOW
<% end %>
</td>
<td><%= cp.supplier.name %></td>
<td><%= number_to_currency(cp.price) %></td>
</tr>
<% end %>
</table>
<%= link_to new_product_costprice_path(@product) do %>
NEW
<% end %>
由new和edit使用。有了新的,这仍然行不通。必须添加一些用于添加供应商ID的逻辑。这可以正常编辑并正确更新价格。
<%= form_for [@product, @costprice] do |f| %>
<div class="field">
<%= f.label :price %><br>
<%= f.text_field 'price', :value => number_to_currency(@costprice.price) %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
link_to助手假定这个嵌套资源:
resources :suppliers
resources :products do
resources :costprices
end
此时,一切运作良好,除了&#34; NEW&#34;行动。可以单击SHOW操作和EDIT操作。单击“新建”操作会生成&#34;未定义的方法 costprices_path &#34;错误。
显示/home/ubuntu/workspace/app/views/costprices/_form.html.erb其中 第1行引出:未定义的方法`costprices_path&#39;对于#&lt;#:0x007f763dca5160&gt;
提取的来源(第1行):
<%= form_for [@product, @costprice] do |f| %>
我明白,这些资源不会生成方法 costprices_path 。但是他们生成了一个方法 new_product_costprice_path(product_id),并且不应该调用此方法点击新建? 顺便说一句,网址对我来说似乎没问题 / products / 1 / costprices / new
主要是我对这个错误的解释和正确的解决方案感兴趣。我用一个&#34;通用解决方案/模式&#34;来领导这篇文章。除了这个错误,我还不确定如何设计一个舒适的用户界面(表单)来处理丰富的多对多关联/嵌套表单。如果某人有解决此类模式的良好链接,请分享。
def new
@costprice = Costprice.new
end
答案 0 :(得分:1)
此错误可能是由new.html.erb
或来自您的控制器的新操作引起的,请检查您是否已将costprices_path
添加到新操作中的new.html.erb
或redirect_to @costprices
。
如果您不熟悉m-to-m表单,可以试用simple_form,它非常易于使用,因为它可以为您处理m-to-m,请查看从simple_form中删除f.association
。
答案 1 :(得分:1)
在costprices_controller
我忘了为新动作设置产品。
错误:before_action :set_product, only: [:show, :edit, :update, :destroy]
正确:before_action :set_product, only: [:new, :show, :edit, :update, :destroy]
不要盲目依赖“铁轨魔法”,直到你真正理解幕后的一切。这是学习rails的重要部分。希望(我仍然不是他们的)之后依靠这个“神奇”来节省大量时间一次又一次地编写样板代码行是很有趣的。
首先,我甚至不知道哪些信息对于识别问题很重要。所以我不得不编辑三到四次这篇帖子提供缺失的信息。这意味着,我对rails路由有一些误解。我假设幕后有太多的“魔力”。我认为将对网址进行分析,并以某种方式神奇地调用正确的命名路线。这只是正确的一半。 <%= form_for [@product, @costprice] do |f| %>
不是真正的魔法,并且基本上负责调用正确的命名路由(它不是url)。如果未设置@product
(没有人为我设置@product,我必须在控制器中执行此操作)此构造等于<%= form_for [@costprice do] |f| %>
,这会导致对指定路由{{1}的无效调用},当然不存在。