0

我的rails应用程序中有以下link_to循环

<%= link_to 'Up', Product.find(n.id).update_attribute(:opinion, true)%>

但我无法更新它。因为它给了我错误

undefined method `model_name' for TrueClass:Class

所以,我想知道在这种情况下更新布尔字段的正确方法是什么?

4

2 回答 2

2

单击链接后您不会更新意见,而是在页面呈现时更新它。

假设您的页面只有以下代码:

<%= link_to 'Up', Product.find(n.id).update_attribute(:opinion, true)%>

当您点击该页面时,实际发生的情况是包裹的代码<%= %>被执行并用于生成一个字符串,该字符串将成为您的 HTML。因此,在简化表达式的同时,在执行的一个步骤中,您将拥有以下代码:

<%= link_to 'Up', true %>

这将生成 HTML

<a href="true">Up</a>

这不是你想要的。

解决方案

在您的产品控制器上创建一个接收产品 ID、更新产品并重定向回来的操作。所以,像这样:

在你的 route.rb 上

 resource :products do
   member do
     post 'update_opinion'
   end
 end

在您的 products_controller.rb 上:

 def update_opinion
   Product.find(params[:id]).update_attribute(:opinion, true)
   redirect_to :back
 end

在你看来:

<%= link_to 'up', update_opinion_project_path(n) %>
于 2013-05-03T20:59:39.243 回答
2

您的代码所做的事情与您似乎追求的完全不同。

辅助方法link_to接受两个参数:链接文本和链接目标,可以是:

  • 一个字符串,例如:'http://stackoverflow.com';
  • 引用内部 URL 的所有单个组件的哈希,由routes定义;
  • 一个对象,或者一个对象数组。

作为第二个参数,您传递一个表达式:

Product.find(n.id).update_attribute(:opinion, true)

这是在代码第一次运行时评估的,即在渲染期间。该表达式尝试立即更新属性,然后返回一个布尔值,说明操作是否成功:如果成功更新属性则为 true,否则为 false。

在您的情况下,它似乎是成功的:它返回true.

现在,true它既不是字符串也不是散列,因此它被视为一个对象,其类为TrueClass. 所以它把它当作一个模型,但不是模型,它没有定义模型方法;因此错误。

您要做的是将代码放入控制器中,并将相对于正确控制器操作的 URL 作为link_to.

于 2013-05-03T21:06:24.247 回答