【问题标题】:NoMethodError when passing path to rails partial将路径传递给rails部分时出现NoMethodError
【发布时间】:2013-05-27 17:29:13
【问题描述】:

我有 3 个模型共享这种相似的表单来提交投票。这个表格包含在每个模型展示页面中,所以我想把这段代码放到一个部分中来清理所有东西。

questions/show.html.erb

<div class="vote">
    <div id="questions">
      <h1><%= @question.votes_count %></h1>
    </div>
    <%= link_to "up", vote_question_path(@question, value: 1), remote: true, method: "post" %>
    <%= link_to "down", vote_question_path(@question, value: -1),remote: true, method: "post" %>
</div>

我已尝试按照以下代码将此代码移动到部分代码中:

投票/_form.html.erb

<div class="vote">
    <div id="votes_count">
        Votes: <%= object.votes_count %>
    </div>
    <%= link_to "up", vote_path(object, value: 1),remote: true, method: "post" %>
    <%= link_to "down", vote_path(answer, value: -1), remote: true,  method: "post" %>
</div>

我将显示页面中的先前代码替换为以下调用以呈现部分:

<%= render partial: "votes/form", locals: {object: @question, vote_path: answer_question_path } %>

但是,尝试各种字符串方法以及 send(path) 方法将 vote_question_path 传递到部分时,它总是会出错with NoMethodError undefined method "vote_path"

我怎样才能正确、干净地将这些路径传递到这个特定的部分?

如果有人需要更多代码,请大声疾呼。

【问题讨论】:

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


    【解决方案1】:

    Rails 会按照自己的方式做事,尝试立即评估路径,因此失败了。但是,根据您的 Ruby 版本,您可以尝试直接传递方法对象,如下所示:

    <%= render partial: "votes/form", locals: {object: @question, vote_path: method(:answer_question_path) } %>
    

    然后,投票/_form

    <div class="vote">
        <div id="votes_count">
            Votes: <%= object.votes_count %>
        </div>
        <%= link_to "up", vote_path.call(object, value: 1), remote: true, method: "post" %>
        <%= link_to "down", vote_path.call(object, value: -1), remote: true,  method: "post" %>
    </div>
    

    请看:http://ruby-doc.org/core-1.9.3/Object.html#method-i-method

    【讨论】:

    • 感谢 christianblais 和 zolter 的回答,作为记录,两种解决方案都可以完美运行,我将 christianblais 的答案标记为正确,因为视图中的代码更少。如果有人有任何建议可以被认为是最佳实践,我们很乐意接受。
    【解决方案2】:

    你可以这样做:

    <%= render partial: "votes/form", locals: {object: @question, up_vote_path: vote_question_path(@question, value: 1), down_vote_path: vote_question_path(@question, value: -1) }  %>
    

    投票/_form

    <div class="vote">
        <div id="votes_count">
            Votes: <%= object.votes_count %>
        </div>
        <%= link_to "up", up_vote_path,remote: true, method: "post" %>
        <%= link_to "down", down_vote_path, remote: true,  method: "post" %>
    </div>
    

    【讨论】:

      【解决方案3】:

      我认为在您的情况下,您可以使用前面 cmets 中概述的任何一种方法。但是,这两种方法之间存在细微差别。

      假设有人有这个代码(这也是你的情况)

      questions/show.html.erb

      <div class="vote">
          <div id="questions">
            <h1><%= @question.votes_count %></h1>
          </div>
          <%= link_to "up", vote_question_path(@question, value: 1), remote: true, method: "post" %>
          <%= link_to "down", vote_question_path(@question, value: -1),remote: true, method: "post" %>
      </div>
      

      在这种情况下,以下部分可以正常工作:

      <%= render partial: "votes/form", locals: {object: @question, up_vote_path: vote_question_path(@question, value: 1), down_vote_path: vote_question_path(@question, value: -1) }  %>
      

      但是,如果我们假设某人拥有此代码(某人必须遍历一个集合):

      questions/show.html.erb

      <% @users.each do | user | %>
        <div class="vote">
            <div id="questions">
              <h1><%= @question.votes_count %></h1>
            </div>
            <%= link_to "up", vote_question_path(user, @question, value: 1), remote: true, method: "post" %>
            <%= link_to "down", vote_question_path(user, @question, value: -1), remote: true,  method: "post" %>
        </div>
      <% end %>
      

      这种方法是行不通的,因为没有办法在渲染的地方获取那些集合项。在这种情况下,vote_path: method(:answer_question_path) 更好。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-08-28
        • 2013-01-16
        • 2011-06-09
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多