铁路上的红宝石-模型中的attr_accessor问题

时间:2018-09-12 03:22:32

标签: ruby-on-rails

我是新手Rails编程器,获取数据时遇到问题。我的用户模型

class User < ActiveRecord::Base 
attr_accessor :name

我的UserController

@users = User.all

我的视图users / index.html.erb

 <% @users.each do |user| %>
<%= user.name %> //error: undefined method `name`

但是如果我在用户模型中删除attr_accessor:name,则我的应用程序将运行。 请告诉我哪里错了

我的rails版本是5。

1 个答案:

答案 0 :(得分:1)

attr_accessor是类级别的方法。您正在尝试在实例级别使用它。

改为尝试cattr_accessor。尽管您不需要attr_accessorcattr_accessor来访问架构中定义的ActiveRecord::Base模型的属性。

=====>编辑<====下面的更正答案

忽略以上建议。这不准确。我将其留作参考。出现undefined method: name错误的原因是因为您已经在通过attr_accessor动态设置了吸气剂的模型上设置了ActiveRecord::Base

attr_accessor模型数据库列的属性上设置ActiveRecord::Base会引起某种冲突。当您删除attr_accessor方法并改为添加与其完全等效的内容时...

def name
  name
end

,然后尝试调用您的调用得到无限递归循环,因为上面定义的.name getter方法正在调用自身,而不访问实际上从数据库中提取数据的ActiveRecord getter方法。

我猜想active_record模型类将以某种方式向您抛出undefined method错误,而不是进行以stack level too deep错误结尾的递归调用。

但是,由于您没有遇到stack too deep错误,所以我的下一个猜测是,在Rails仍尝试访问覆盖的方法时,您定义的attr_accessor会覆盖动态创建的ActiveRecord::Base吸气剂(不再存在)。可能导致undefined method 'name'错误。

但是...

当您以这种方式添加自己的getter方法时...那么它将起作用...

def name
  super
end

这是因为使用super,您的类仅继承了其动态定义的ActiveRecord::Base getter方法的行为。您可以通过添加...

对此进行测试。
def name
  super
  'Foo'
end

当您致电@model.name时,您会看到返回了Foo。从方法中删除“ Foo”,返回的是对动态创建的super getter方法的ActiveRecord::Base调用。

我随时可以编辑和输入此答案。这是我在控制台中进行测试并阅读后得出的合乎逻辑的结论。

何时使用attr_accessor

此外,还要进一步回答您有关何时使用attr_accessor ...

的问题

当您要创建和存储与业务逻辑以及模型相关的信息,并且仅在请求/实例生命周期的整个过程中持续使用时,可以使用此方法。

例如原始密码(尽管我不愿意操纵原始密码的人)

或类似的东西

@stock.current_price

其中@stockActiveRecord::Base对象,但是.current_price是在实例化@stock对象时从API计算或检索的,因为持久化和从数据库中检索一个不断变化的值,例如在任何给定时间点的股票价格。