【问题标题】:Accessing a model instance from a different model's controller从不同模型的控制器访问模型实例
【发布时间】:2010-08-02 06:51:11
【问题描述】:

我有一个线程模型,它有一个show 页面,在该操作的视图代码中我有:

<%= render 'comments/form' %>

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

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

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


最后,我应该走哪条路?


更新

为了澄清,

  • 我在线程控制器中创建了一个新注释。 @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 关系。

【问题讨论】:

  • 您为什么要在评论控制器的创建操作中访问已经创建的评论?如果它已经创建,那么该操作还需要做什么?
  • rspeicher,评论是由build创建的,但这只会设置评论的thread_id。我还需要填写作者、标题、内容等。

标签: ruby-on-rails ruby


【解决方案1】:

您确定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

然后在您的 cmets 控制器中,您将在 params 哈希中获得 spool_id。对于现有 cmets,路径将如下所示:

/spools/1/comments/2

对于新的 cmets 也是如此

/spools/1/comments/

params[:spool_id] 设置为 1。

【讨论】:

  • 我更改了型号名称,以便它们更传统。我的线程模型实际上叫做 Spool。
  • 我现在可以创建评论,但它没有thread_id。如何将线程 ID 传递给 Comment 控制器?
  • 谢谢,我现在正在观看关于嵌套资源的 Railscast。这正是我想要的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-11
  • 2018-11-15
  • 2012-08-23
  • 2011-10-22
  • 2013-07-05
相关资源
最近更新 更多