Ruby on Rails - 将变量传递到嵌套局部视图中

9
我将通过 :collection 选项向 _feed_item 部分传递一个集合 (@feed_items)。在 _feed_item 部分内,我想要呈现另一个部分 _like_button。在 _like_button 部分中,我想要能够访问集合的特定成员。请问我需要从 _feed_item 部分传递什么到 _like_button 部分?
 @feed_items = current_user.user_feed.order("id DESC").limit(5)

_feed.html.erb

 <%= render partial: 'shared/feed_item', collection: @feed_items %>

_feed_item.html.erb

 <%= render 'likes/like_button', ????? %>

_like_button.html.erb

 <% if like = current_user.likes.find_by_feed_id(feed_item.id) %>

编辑

根据下面的答案,将本地变量传递是可行的:

 <%= render :partial => 'likes/like_button', :locals =>{:feed_item => feed_item} %>

然而,当我提交赞时,它尝试通过 ajax 再次渲染表单时,出现了 ActionView::Template::Error (undefined local variable or method 'feed_item' 的错误。我该如何再次通过 ajax 调用传递本地变量?

控制器

class LikesController < ApplicationController
  def create
    @like = Like.create(params[:like])
    @feed = @like.feed
    render :toggle
  end

  def destroy
    like = Like.find(params[:id]).destroy
    @feed = like.feed
    render :toggle
  end
end

toggle.js.erb

 $("#like").html("<%= escape_javascript render('like_button') %>");

_like_button.html.erb

 <% if like = current_user.likes.find_by_feed_id(feed_item.id) %>
  <%= form_for like, :html => { :method => :delete }, :remote => true do |f| %>
    <%= f.submit "Unlike" %>
  <% end %>
 <% else %>
  <%= form_for current_user.likes.build(:feed_id => feed_item.id), :remote => true do |f| %>
   <%= f.hidden_field :feed_id %>
   <%= f.hidden_field :user_id %>
   <%= f.submit "Like" %>
  <% end %>
 <% end %>

_feed_item.html.erb

    <div id="like">
      <%= render :partial => 'likes/like_button', :locals =>{:feed_item => feed_item} %>
    </div>
4个回答

8

谢谢。它有效(数据库正在更新),但是我仍然在控制台中收到一个错误 ActionView::Template::Error (undefined local variable or method 'feed_item' for #<#<Class:0x00000102f6b078>:0x0000010452f7d8>)。你有什么想法是什么原因导致的吗? - diasks2
添加完整的跟踪检查,以确定它已经遍历了哪些文件。 - Pritesh Jain
也许你正在从其他表单调用它,本地变量也需要从那里传递。 - Pritesh Jain
错误实际上是在通过AJAX调用再次呈现表单时发生的。`Rendered likes/_like_button.html.erb (17.3ms) Rendered likes/create.js.erb (18.4ms) Completed 500 Internal Server Error in 30msActionView::Template::Error (undefined local variable or method 'feed_item' for #<#Class:0x000001046b46f8:0x00000105c71f68>): 1: <% if like = current_user.likes.find_by_feed_id(feed_item.id) %> 2: <%= form_for like, :html => { :method => :delete }, :remote => true do |f| %> 3: <%= f.submit "Unlike" %> 4: <% end %>`. - diasks2
这是我的JavaScript嵌入式Ruby文件。我如何将本地变量传递给它呢?$("#like").html("<%= escape_javascript render('like_button') %>"); - diasks2
以相同的方式呈现,像我在这里回答一样,使用本地变量并分配适当的对象。 - Pritesh Jain

1

您需要将feed_item变量作为本地变量传递给_like_button.html.erb局部文件。

<%= render 'likes/like_button', :locals => { :feed_item => feed_item } %>

这只是将内部局部中的本地命名为feed_item设置为与外部局部中的feed_item相同。


谢谢。它有效(数据库正在更新),但是我仍然在控制台上收到错误ActionView::Template::Error (undefined local variable or method 'feed_item' for #<#<Class:0x00000102f6b078>:0x0000010452f7d8>)。你有什么想法可能导致这种情况发生? - diasks2
创建一个实例变量(@feed_item)作为feed_item,并在内部局部文件中使用@feed_item而不是feed_item,以避免错误。 - Jimmy Thakkar

1

当使用集合来渲染局部文件时,您将获得与渲染文件名相同的本地变量。因此,您只需将文件名作为本地变量传递即可。

例如,如果您有_feed_item.html.erb,并且您正在使用集合来呈现此局部文件,则可以这样:

render "feed_item", collection: @feed_items

因此,在此 feed_item 局部中,您将获取 feed_item 本地变量。

因此,您可以将此 feed_item 变量作为本地变量传递给另一个局部(在您的情况下是 _like_button.html.erb)。


谢谢。它有效(数据库正在更新),但是我仍然在控制台中收到一个错误 ActionView::Template::Error (undefined local variable or method 'feed_item' for #<#<Class:0x00000102f6b078>:0x0000010452f7d8>)。你有什么想法是什么原因引起的吗? - diasks2
你可以告诉我在哪里获取这个“feed_item”吗? - Mohanraj

0

如果我理解正确,你需要做以下操作:

_feed.html.erb

 <%= render partial: 'shared/feed_item', collection: @feed_items %>

_feed_item.html.erb

在这里,你正在定义一个名为feed_item的局部变量,并将其值分配为集合的每个元素。你可以省略locals这个词,因为Rails足够聪明,知道它是一个local变量。

 <% @feed_items.each do |feed_item| %>
 <%= render 'likes/like_button', feed_item: feed_item %>
 <% end %>

_like_button.html.erb

 <% if like = current_user.likes.find_by_feed_id(feed_item.id) %>

希望它能对你有所帮助。


谢谢你的帮助。现在我遇到了一个问题,在ajax更新后无法呈现表单(请参见我对上面问题的编辑)。你知道可能出了什么问题吗? - diasks2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接