从不同模型的控制器访问模型实例

时间:2010-08-01 17:59:19

标签: ruby-on-rails ruby

我有一个具有show页面的Thread模型,并且在该操作的视图代码中我有:

<%= render 'comments/form' %>

初始化新评论的正确方法是什么?我试过了:

    注释创建操作中的
  • @comment = @thread.comments.build(params[:comment])和注释表单的视图代码。
  • 线程辅助方法和模型方法称为this_thread
  • 在线程的@comment控制器代码中初始化show

所有这些尝试都导致了nil对象错误或未定义的方法错误。


总之,我应该追求哪条道路?


更新

澄清,

  • 我在Thread控制器中创建了一个新注释。 @comment = @thread.comments.build
  • 在评论create操作中,如何访问我在线程控制器中创建的@comment?

更新#2

评论控制器:

def create
  thread = Thread.find(params[:id])
  @comment = thread.comments.build(params[:thread])

  if @comment.save
  ...
end

给了我这个错误:

Couldn't find Thread without an ID
你知道为什么吗?我假设它与params[:id]是注释ID而不是线程ID有关。那么,我如何获得线程ID?或者,我忘记依赖的Rails魔法,因为这是has_many / belongs_to关系。

1 个答案:

答案 0 :(得分:2)

您确定Thread.new正在创建模型的实例吗? Ruby有一个线程库,它也定义了一个Thread类 - 你可能有一个名字冲突。

  

在评论创建动作中,我该怎么做   访问我创建的@comment   线程控制器?

从技术上讲,你没有。当您的视图发布到Comment控制器时,必须创建一个新对象,例如@comment = Comment.new(params[:comment]。或者,如果您要从数据库中检索,@comment = Comment.find(params[:id]).请注意build不保存对象。

修改

要获取控制器中的线程,您有两个选择。一种方法是将其作为已发布表单的一部分传递(通常使用隐藏字段)。

更好的方法是使用嵌套路由并让Rails为您完成工作。如果您的路线如下:

map.resources :spools do |spools|
  spools.resources :comments
end

然后在您的评论控制器中,您将在params哈希中获得spool_id。对于现有注释,路径将如此:

/spools/1/comments/2

和新评论一样

/spools/1/comments/

params[:spool_id]设置为1。