Rails - 从父

时间:2015-07-24 18:16:19

标签: ruby-on-rails

感觉自己像是一个白痴问这个,但我开始觉得我原来是以错误的方式学习它。

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

如果我有两个型号:

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参数存活,这将有效。但是,只要用户通过后退按钮或渲染“新”&#39;来到此页面上。由于验证失败,url参数丢失,这不再有效。

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

2 个答案:

答案 0 :(得分: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参数,验证失败会提示你回到正确的页面。

答案 1 :(得分:0)

您在控制器操作中定义的所有实例变量都存在于视图中。因此,如果您在控制器中定义@category,则可以使用<%= @category %>在视图中访问它。这样您就可以避免在视图中使用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 %>