在 Rails 中使用自联接添加新记录

Hea*_*son 3 ruby-on-rails

我在一个对象“东西”上有一个自我连接

class Thing < ActiveRecord::Base  
    has_many :children, :class_name => "Thing", :foreign_key => "parent_id"  
    belongs_to :parent, :class_name => "Thing"    
end
Run Code Online (Sandbox Code Playgroud)

当我查看一个事物时,我想提供一个指向新事物页面的链接来创建一个子对象,其 parent_id 填充了当前事物的 id,所以我想我会使用这个

<%= link_to 'New child thing', new_thing_path(@thing) %>
Run Code Online (Sandbox Code Playgroud)

但这不起作用,因为默认操作是针对控制器中的 GET 方法,该方法在参数中找不到 :id

@thing = Thing.find(params[:id])
Run Code Online (Sandbox Code Playgroud)

所以问题是;

a) 我应该为儿童配备一个新的控制器吗?
b) 是否有更好的方法将 parent_id 的参数发送到 Thing 控制器中的 GET 方法

提前致谢

希思。

Dan*_*nne 5

您不必为此目的创建新的控制器。您还可以在现有控制器中使用一些额外的路由和操作来完成。如果您已经将 Thing 控制器映射为资源,则可以添加如下附加路由:

map.resources :things, :member => { :new_child => :get, :create_child => :post }
Run Code Online (Sandbox Code Playgroud)

这将为您提供两条额外的路线:

new_child_thing     GET   /things/:id/new_child(.:format)
create_child_thing  POST  /things/:id/create_child(.:format)
Run Code Online (Sandbox Code Playgroud)

然后您可以将这两个操作添加到您的控制器并处理其中的创建

def new_child
  @parent_thing = Thing.find(params[:thing_id])
  @thing = Thing.new
  ...
end

def create_child
  @parent_thing = Thing.find(params[:thing_id])
  @thing = Thing.new(params[:thing])
  @thing.parent = @parent_thing
  if @thing.save
    render :action => :show
  else
    render :action => :new_child
  end
end
Run Code Online (Sandbox Code Playgroud)