rails 4 undefined局部变量呈现部分has_many_through

时间:2016-07-18 22:56:53

标签: ruby-on-rails ruby-on-rails-4

我正在尝试在has_many_through关联中显示所有用户帖子的所有评论。

routes.rb中:

resources :posts do
  resources :comments
end

模型:

class User < ActiveRecord::Base
  has_many :posts, dependent: :destroy
  has_many :comments, :through => :posts, dependent: :destroy
end

class Post < ActiveRecord::Base  
  belongs_to :user
  has_many :comments, dependent: :destroy
end

class Comment < ActiveRecord::Base
  belongs_to :user
  belongs_to :post
end

users_controller.rb

def activity
  @user = current_user
  @posts = @user.posts
  @comments = @user.comments
end

activity.html.erb

<h4>My Activity</h4>
<ol class="posts">
  <%= render @comments.last(3) %>
</ol>

_comment.html.erb

<div class="comment" id="comment-<%= post.id %>-<%= comment.id %>">
    <%= link_to smavatar_for(comment.user), user_path(comment.user.name) %>
    <span class="user"><%= link_to comment.user.name, user_path(comment.user.name) %></span>
  <div class="comment-content">
    <%= simple_format(comment.content) %>
  </div>
</div>

activity.html.erb中的行<%= render @comments.last(3) %>给出了错误

  

未定义的局部变量或方法`post'for Class

表示_comment.html.erb中的行<div class="comment" id="comment-<%= post.id %>-<%= comment.id %>">。我知道我可能需要将局部变量传递给partial,我只是无法弄清楚如何去做。 <%= @comments.last(3) %>而不是<%= render @comments.last(3) %>将所有注释参数打印到视图中,因此它识别集合。添加locals: { comment: @comment, post: @post }仍会获得Class的未定义局部变量帖子,post: @comment.post会收到nilClass错误。我已经过了所有的SO和RoR指南后退和前进渲染部分,我仍然不清楚什么时候通过,所以一般的任何帮助都是值得赞赏的。

2 个答案:

答案 0 :(得分:2)

Post本身

引用Comment

假设每个Comment都有一个belongs_to :post关联

使用与

完全相同的快捷语法调用partial
<%= render @comments.last(3) %>

在部分内部,使用comment.postcomment.post_id获取Post数据

E.g。

<div class="comment" id="comment-<%= comment.post_id %>-<%= comment.id %>">
    <%= link_to smavatar_for(comment.user), user_path(comment.user.name) %>
    <span class="user"><%= link_to comment.user.name, user_path(comment.user.name) %></span>
  <div class="comment-content">
    <%= simple_format(comment.content) %>
  </div>
</div>

在此方案中无需使用locals

请注意,您尝试通过@post选项传递locals,但是在您的控制器中,您有一个@posts变量(复数),而不是@post单数。

由于每个Comment记录可能属于不同的Post,因此您无法为Post传递任何选项。

使用locals的唯一另一种方法是将部分分解为循环并单独渲染每个Comment,例如。

<% @comments.last(3).each do |comment| %>
   <%= render comment, post: comment.post %>
   <!-- OR -->
   <%= render partial: "comments/comment", locals: { comment: comment, post: comment.post } %>
<% end %>

请注意,我们仍需要致电comment.post以获取与Post相关联的Comment。因此,使用快捷语法并引用部分内Post的{​​{1}}更为简单。

答案 1 :(得分:0)

您需要在_comment.html.erb中将post.id更改为comment.post.id而不传递locals的不同视角,它更加清晰简洁

<div class="comment" id="comment-<%= comment.post.id %>-<%= comment.id %>">
  <%= link_to smavatar_for(comment.user), user_path(comment.user.name) %>
  <span class="user"><%= link_to comment.user.name, user_path(comment.user.name) %></span>
  <div class="comment-content">
    <%= simple_format(comment.content) %>
  </div>
</div>

有效吗?