简体   繁体   中英

Rails - 3 nested models in one view

I'm struggling with grasping the fundamentals behind writing model methods, which is I think what I need to do to get this to work. Basically, I have a project view that's showing project_todos that belong to that project. Then nested under that I have project_todo_comments that belong to a project_todo. All in one view.

I've set up the associations so that project has_many project_todos, project_todo belongs_to project and has_many project_todo_comments. Then of course project_todo_comment belongs_to project_todo.

In the projects controller, I'm doing this:

  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

So this is working to the point where I can add todos on a project and display them, and I can also add comments to project todos and display them too, all in that same view. BUT, I'm having difficulties getting the comments to display ONLY with the todos that they're associated with. Right now, when I add a comment on any todo, every single todo then displays that comment.

In the view, here's where I'm displaying the project_todos and nesting the form to add a comment, then displaying the comments:

 <% @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 %>

I've been told that I need to write a model method to get this to work, but I'm still trying to understand those. Could anyone just reassure that I do in fact need to write a model method, and point me in a direction to learn about them? Thanks!

In your controller you get all of the comments, but in an actual todo item you just want the comments for that item. This can be done with: todo.project_todo_comments
The easiest way to solve:

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

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

You can remove the line from your controller:

- @comments = @project.project_todo_comments

However in your form (where you create a comment) you use the wrong ID for the todo item:

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

By the way, I would just name those models: Todo and Comment , there is no point using that long modelnames. You define those associations in the start of your model, so if someone would read it, he/she would see it instantly.

For example see myself, I knew what was the purpose of your models still misused the namings, cause of too long classnames.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM