【问题标题】:Ruby on Rails - Passing variables to a partial within a partialRuby on Rails - 将变量传递给部分中的部分
【发布时间】:2012-08-28 19:33:16
【问题描述】:

我通过 :collection 选项将集合 (@feed_items) 传递给 _feed_item 部分。在 _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>

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-3 partial-views


    【解决方案1】:
     <%= render :partial => 'likes/like_button', :locals =>{:feed_item => feed_item} %>
    

    Rails 有一些很棒的文档http://guides.rubyonrails.org/layouts_and_rendering.html#passing-local-variables

    在toggle.js中

     $("#like").html("<%= escape_javascript(render :partial => 'likes/like_button', :locals =>{:feed_item => @feed}) %>");
    

    【讨论】:

    • 谢谢。这有效(数据库正在更新),但是我仍然在控制台ActionView::Template::Error (undefined local variable or method 'feed_item' for #&lt;#&lt;Class:0x00000102f6b078&gt;:0x0000010452f7d8&gt;) 中遇到错误。知道是什么原因造成的吗?
    • 添加整个跟踪检查它正在遍历哪个文件
    • 可能是您从任何其他形式调用它,并且本地人也需要从那里传递
    • 当它通过ajax调用再次渲染表单时,实际上发生了错误。 Rendered likes/_like_button.html.erb (17.3ms) Rendered likes/create.js.erb (18.4ms) Completed 500 Internal Server Error in 30ms ActionView::Template::Error (undefined local variable or method 'feed_item' for #&lt;#&lt;Class:0x000001046b46f8&gt;:0x00000105c71f68&gt;): 1: &lt;% if like = current_user.likes.find_by_feed_id(feed_item.id) %&gt; 2: &lt;%= form_for like, :html =&gt; { :method =&gt; :delete }, :remote =&gt; true do |f| %&gt; 3: &lt;%= f.submit "Unlike" %&gt; 4: &lt;% end %&gt;
    • 这是我的 JavaScript 嵌入式 Ruby 文件。我怎样才能将局部变量也传递给它? $("#like").html("&lt;%= escape_javascript render('like_button') %&gt;");
    【解决方案2】:

    您需要将 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 #&lt;#&lt;Class:0x00000102f6b078&gt;:0x0000010452f7d8&gt;) 中仍然出现错误。知道是什么原因造成的吗?
    • 将 feed_item 创建为实例变量 (@feed_item),然后在内部部分中使用 @feed_item 而不是 feed_item 来避免错误。
    【解决方案3】:

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

    例如,如果您有 _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 #&lt;#&lt;Class:0x00000102f6b078&gt;:0x0000010452f7d8&gt;) 中仍然出现错误。知道是什么原因造成的吗?
    • 你在哪里提供这个“feed_item”,我可以知道吗?
    【解决方案4】:

    如果我理解,您必须执行以下操作:

    _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 更新后呈现表单(请参阅我对上述问题的编辑)。你知道可能出了什么问题吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-16
    • 2011-06-09
    • 1970-01-01
    • 2013-07-05
    • 1970-01-01
    • 1970-01-01
    • 2012-06-21
    相关资源
    最近更新 更多