【问题标题】:rails 4 undefined local variable rendering partial has_many_throughrails 4未定义的局部变量渲染部分has_many_through
【发布时间】:2016-11-21 16:17:06
【问题描述】:

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

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 中的&lt;%= render @comments.last(3) %&gt; 行给出了错误

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

对于 _comment.html.erb 中的 &lt;div class="comment" id="comment-&lt;%= post.id %&gt;-&lt;%= comment.id %&gt;"&gt; 行。我知道我可能需要将局部变量传递给局部变量,我只是不知道该怎么做。 &lt;%= @comments.last(3) %&gt; 而不是 &lt;%= render @comments.last(3) %&gt; 将所有评论参数打印到视图中,因此它可以识别集合。添加locals: { comment: @comment, post: @post } 仍然得到我未定义的类局部变量帖子,而post: @comment.post 得到一个 nilClass 错误。我一直在研究 SO 和 RoR Guides 来回渲染局部,但我仍然不清楚何时通过什么,所以一般来说,任何帮助都是值得赞赏的。

【问题讨论】:

  • 您是否也在同一页面中呈现帖子?我看不出你如何渲染 cmets 有任何问题
  • @Marv-C,我可以在同一页面上呈现帖子,并且它们呈现得很好,但我希望这个视图只呈现用户在他们的帖子中从其他人那里收到的 cmets。

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


【解决方案1】:

Comment 本身引用Post

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

完全按照您的方式使用快捷语法调用部分

<%= render @comments.last(3) %>

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

例如

<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

请注意,您尝试通过 locals 选项传递 @post,但是在您的控制器中,您有一个 @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 来获取与Comment 关联的Post。因此,仅使用快捷语法并在部分中从 Comment 引用 Post 会简单得多。

【讨论】:

  • @JimHogan 很高兴我能帮上忙!
【解决方案2】:

不同的视角你只需将_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>

有用吗?

【讨论】:

  • 太糟糕了,我输了比赛:D
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-05-05
  • 1970-01-01
  • 2011-05-14
  • 2012-03-04
  • 2016-01-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多