【问题标题】:Rails - 3 nested models in one viewRails - 一个视图中的 3 个嵌套模型
【发布时间】:2012-12-14 15:08:54
【问题描述】:

我正在努力掌握编写模型方法背后的基本原理,我认为我需要做些什么才能让它发挥作用。基本上,我有一个项目视图,它显示属于该项目的 project_todos。然后嵌套在我有属于 project_todo 的 project_todo_cmets 之下。一个视图。

我已经建立了关联,以便项目 has_many project_todos、project_todo belongs_to project 和 has_many project_todo_cmets。然后当然是 project_todo_comment belongs_to project_todo。

在项目控制器中,我正在这样做:

  def show
    @project = Project.find(params[:id])

    # Display the form to create a new todo
    @project_todo = ProjectTodo.new

    # Create the instance variable to display the loop in the view
    @todos = @project.project_todos

    # Display the form to create a new comment
    @project_todo_comment = ProjectTodoComment.new

     # Create the instance variable to display the loop in the view
    @comments = @project.project_todo_comments

    respond_to do |format|
      format.html # show.html.erb
      format.json { render :json => @project }
    end
  end

因此,我可以在项目中添加待办事项并显示它们,我还可以将 cmets 添加到项目待办事项并显示它们,所有这些都在同一个视图中。但是,我很难让 cmets 仅显示与它们相关联的待办事项。现在,当我对任何待办事项添加评论时,每个待办事项都会显示该评论。

在视图中,我在这里显示 project_todos 并嵌套表单以添加评论,然后显示 cmets:

 <% @todos.each do |todo| %>
    <p><%= todo.title %></p>

    <%= form_for(@project_todo_comment) do |f| %>
        <%= f.hidden_field :project_todo_id, :value => @project_todo.id %>
        <%= f.hidden_field :project_id, :value => @project.id %>
        <%= f.text_area :comment %>
        <%= f.submit 'Add Comment' %>
    <% end %>

    <% @comments.each do |comment| %>
        <%= comment.comment %>
    <% end %>

  <% end %>

有人告诉我,我需要编写一个模型方法才能使其工作,但我仍在努力理解这些。谁能保证我确实需要编写一个模型方法,并指出我了解它们的方向?谢谢!

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-3 models


    【解决方案1】:

    在您的控制器中,您可以获得所有 cmets,但在实际的 todo 项目中,您只需要该项目的 cmets。这可以通过以下方式完成:todo.project_todo_comments
    最简单的解决方法:

    - <% @comments.each do |comment| %>
    -   <%= comment.comment %>
    - <% end %>
    
    + <% todo.project_todo_comments.each do |comment| %>
    +   <%= comment.comment %>
    + <% end %>
    

    您可以从控制器中删除该行:

    - @comments = @project.project_todo_comments
    

    但是在您的表单(您创建评论的地方)中,您为待办事项使用了错误的 ID:

    - <%= f.hidden_field :project_todo_id, :value => @project_todo.id %>
    + <%= f.hidden_field :project_todo_id, :value => todo.id %>
    

    顺便说一下,我只想为这些模型命名: TodoComment,使用那么长的型号名称毫无意义。您在模型开始时定义这些关联,因此如果有人阅读它,他/她会立即看到它。

    例如看看我自己,我知道你的模型的目的是什么仍然滥用命名,导致类名太长。

    【讨论】:

    • 但是 cmets 是未定义的。应该改为&lt;% todo.project_todo_comments.each do |comment| %&gt; 吗?
    • 是的,我更正了我的答案,我被窃听了,因为这些类名有点长。
    • 嗯,好吧。所以这样做时我没有收到任何错误,但是 cmets 现在根本不显示,即使我添加了新的 todo 和新的 cmets。我想我不明白当您从控制器中取出 @comments 实例变量时这是如何工作的。它现在如何访问模型?仅仅是因为 has_many belongs_to 关联吗?
    • 所以你用each方法迭代@todos,你得到一个todo项目。你也可以在你的视图中使用对象方法(但是尽量保持最小化以保持 MVC 风格)。所以基本上你需要在你的表单中使用这个todo 项目来真正加入对该项目的评论。 (更新了我的答案)
    • 太棒了,这很有意义并且有效!谢谢。但是我仍然不明白如果控制器中没有一个实例变量可以让您访问 project_todo_cmets 模型,我们该怎么做todo.project_todo_comments
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-10
    • 2012-01-04
    • 1970-01-01
    • 2012-01-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多