我是新手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。
答案 0 :(得分:1)
attr_accessor是类级别的方法。您正在尝试在实例级别使用它。
改为尝试cattr_accessor
。尽管您不需要attr_accessor
或cattr_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
其中@stock
是ActiveRecord::Base
对象,但是.current_price
是在实例化@stock
对象时从API计算或检索的,因为持久化和从数据库中检索一个不断变化的值,例如在任何给定时间点的股票价格。