【问题标题】:Ruby on Rails: render partial form for each user found from search resultsRuby on Rails:为从搜索结果中找到的每个用户呈现部分表单
【发布时间】:2016-04-26 15:23:48
【问题描述】:

是否可以为我作为搜索结果获得的每个用户从共享部分呈现表单?

所以当我搜索adam 时,我会得到类似的信息:

Adam1 [跟随形式]

Adam2 [跟随形式]

Adam3 [跟随形式]

其中follow form是一个follow button,它保存了与数据库的关系,所以每个button都必须正确发送一个对应的user id。 以下所有机制等都正常工作,您可以在访问用户的个人资料时关注用户,但我现在实现了对用户的搜索,并且在获得结果时,我还希望表单位于每个结果旁边。

我相信我需要做的事情是这样的:

<% for result in @results do
  render result
  render follow_form
%>

或

<% @results.each do |f|
  render f
  render follow_form for f
%>

但我不确定该怎么做。 即使我设法呈现用户,我也无法在他们旁边呈现表单。由于某种原因,@user 容器为零。

这些是搜索控制器的文件和共享表单:

class SearchController < ApplicationController

  def search
    query = "%#{params[:query]}%"
    @users = User.where("name LIKE ? ", query)
  end

end

搜索视图

<%= render 'shared/search_bar' %>
<ul class="users follow">
  <%= @users.each do |f| %>
    <%= render f %>
    <%= render 'shared/endorse_form' if logged_in? %>
    <% end %>
</ul>

在此处的视图 /\ 中,渲染器 f 正确渲染了用户,但也渲染了一些看起来像数据库转储的东西,位于包含用户数据的结果下方。当我添加render shared/endorse_form 时,我收到关于空类undefined methodid' for nil:NilClass` 的错误 在如下所示的 follow(endorse) 表单的第 2 行中:

<%= form_for(current_user.active_endorsements.build, remote: true) do |f| %>
  <div><%= hidden_field_tag :endorsed_id, @user.id %></div>
  <%= f.submit "Endorse", class: "btn btn-primary" %>
  <%= f.text_field :comment, class: 'form-control' %>
<% end %>

如何处理?任何帮助将不胜感激。

所有代码都可以在https://bitbucket.org/kramarz/pracainzynierska获得

【问题讨论】:

  • 它呈现“类似于数据库转储的东西”的原因是&lt;%= @users.each do |f| %&gt; 输出@users.each 的返回值,each 返回它的被调用者,即@users。也就是说,除了循环内的所有内容之外,您还打印了 @users 对象本身,因为这是 each 返回的内容。要解决此问题,请将该行上的 &lt;%= 更改为 &lt;%。
  • @Jordan 谢谢乔丹!你说的有道理!这是一个值得记住的好提示!好的,所以我已经修复了“转储”,只需留下为每个相应用户正确呈现表单,以便“认可”按钮工作并发送正确的数据:(

标签: ruby-on-rails ruby partials


【解决方案1】:

问题是实例变量(如@user)不会自动传递给partials,所以在你的endorse_form partial @user 是nil。 (另外,@user 实际上并不是您想要的对象——您想使用在 @users.each 的每次迭代中产生的对象。)解决方案是使用 locals 选项,它可以让您告诉 render ,您希望在部分中可用的变量以及它们的名称应该是什么:

<%= @users.each do |user| %>
  <%= render user %>
  <%= render partial: 'shared/endorse_form', locals: { endorsed_user: user } if logged_in? %>
<% end %>

我在这里做了两件事。首先,我将f 重命名为user,因为f 作为用户对象的名称实际上没有意义。 (在 Rails 视图中,f 通常指的是一个 FormBuilder 对象,该对象屈服于您传递给 form_for 的块。)

其次,我添加了选项locals: { endorsed_user: user }。这告诉render,“我希望有一个名为endorsed_user 的局部变量,我可以在部分中使用它,我希望它的值是user 的值,”这是由此产生的用户对象each 的迭代。

然后,在您的 endorse_form 部分中,您将使用局部变量 endorsed_user 而不是实例变量 @user:

<%= form_for(current_user.active_endorsements.build, remote: true) do |f| %>
  <div><%= hidden_field_tag :endorsed_id, endorsed_user.id %></div>
  <%= f.submit "Endorse", class: "btn btn-primary" %>
  <%= f.text_field :comment, class: 'form-control' %>
<% end %>

【讨论】:

  • 其实你说的有道理,乔丹。但现在我得到了 #的未定义局部变量或方法`endorsed_user'
  • 抱歉,我忘记了当你有选项时,你必须使用render partial: 'foo', ... 而不仅仅是render 'foo', ...。我已经更新了我的答案。
  • 谢谢!好吧,这部分可能会令人困惑,但是,我实际上使用的是呈现另一个部分的部分。 endorse_form 看起来像这样&lt;% unless current_user?(@user) %&gt; &lt;div id="endorse_form"&gt; &lt;% if current_user.endorsing?(@user) %&gt; &lt;%= render 'shared/unendorse' %&gt; &lt;% else %&gt; &lt;%= render 'shared/endorse' %&gt; &lt;% end %&gt; &lt;/div&gt; &lt;% end %&gt;
  • 所以事实上,表单在共享/背书中,我可以进一步将本地从那个部分传递到下一个部分吗?因为我希望他们所有人都可以在用户个人资料上工作。他们从背书变为不背书,这样你就可以给予和收回。如果我将代码更改为使用shared/endorse 而不是shared/endorse_form 它可以正常工作,但是我放弃了收回该背书的选项,我也不能在@user 个人资料页面上使用它。在个人资料页面上,它使用@user 来正常工作......我现在完全迷失了......
  • 是的,endorsed_user 只是一个普通的 Ruby 变量,render 只是一个普通的 Ruby 方法,所以你可以像上面那样传递它,例如render partial: 'shared/endorse', locals: { endorsed_user: endorsed_user }.
猜你喜欢
  • 2013-12-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-20
  • 2012-07-19
  • 1970-01-01
相关资源
最近更新 更多