【问题标题】:Rails - create child record from parentRails - 从父级创建子记录
【发布时间】:2015-07-25 02:48:15
【问题描述】:

问这个问题感觉自己像个白痴,但我开始觉得我最初是用错误的方式学习的。

我可能会注意到我没有使用嵌套路由。

如果我有两个模型:

class Category < ActiveRecord::Base
  has_many :products
end

class Product < ActiveRecord::Base
  belongs_to :category
end

从相应的父类别页面创建新产品的最佳方式是什么?

目前我在分类页面上有这个

<%= link_to new_product_path(:category_id => @category) 

然后在我使用的新产品页面上:

<%= form_for @product do |p| %>
  <%= p.hidden_field :category_id, :value => params[:category] %>
  #rest of fields
  #etc
<% end %>

只要 url 参数存在,这将起作用。但是,一旦用户通过后退按钮或由于验证失败而渲染“新”到达此页面,url 参数就会丢失并且不再起作用。

这是一个非常简单的日常 Rails 任务,必须有一种更可靠的方法从父页面创建子记录。

【问题讨论】:

标签: ruby-on-rails


【解决方案1】:

您可以通过以下方式更改您的新操作和创建操作,就像它们是嵌套的类别产品资源一样工作:

resources :products, except: [:new, :create] do
  get  :new, path: 'products/:category_id/new'
  post :create, path: 'products/:category_id'
end

您仍然需要这样做:

<%= link_to new_product_path(:category_id => @category) %>

但您不必在表单中添加隐藏字段。相反,您可以在控制器内的创建操作中执行以下操作:

category = Category.find params[:category_id]
category.products.build(product_params)

这样做您将不会使用 url 参数,并且验证失败应该会提示您返回正确的页面。

【讨论】:

    【解决方案2】:

    您在控制器操作中定义的所有实例变量都存在于视图中。因此,如果您在控制器中定义@category,您可以使用&lt;%= @category %&gt; 在视图中访问它。这样你就可以避免在你的视图中使用params。

    def new 
      @category = Category.find(params[:category])
    
    def create
      @category = Category.find(params[:category])
    
    <%= form_for @product do |p| %>
      <%= p.hidden_field :category_id, :value => @category.id %>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多