ruby-on-rails - ruby on rail - 模型中的 attr_accessor 问题
问题描述
我是一名新手 Rails 程序员,在获取数据时遇到问题。我的用户模型
class User < ActiveRecord::Base
attr_accessor :name
我的用户控制器
@users = User.all
我的观点 users/index.html.erb
<% @users.each do |user| %>
<%= user.name %> //error: undefined method `name`
但是如果我在用户模型中删除 attr_accessor :name,我的应用程序就会运行。请告诉我有什么问题
我的rails版本是5。
解决方案
attr_accessor 是一个类级别的方法。您正在尝试在实例级别上使用它。
试试cattr_accessor
吧。尽管您不需要attr_accessor
orcattr_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
错误,我的下一个猜测是attr_accessor
您定义的覆盖动态创建的ActiveRecord::Base
getter,而 rails 仍在尝试访问覆盖的方法(不再存在)。可能导致undefined method 'name'
错误。
但...
当您以这种方式添加自己的 getter 方法时......然后它就可以工作......
def name
super
end
这是因为super
您的类只是继承其动态定义的ActiveRecord::Base
getter 方法的行为。您可以通过添加来测试它...
def name
super
'Foo'
end
当你打电话时,@model.name
你会看到它Foo
被退回。从方法中删除“Foo”,返回的是super
对动态创建的ActiveRecord::Base
getter 方法的调用。
我愿意对此答案进行编辑和输入。这是我在控制台中进行测试并阅读后得出的合乎逻辑的结论。
何时使用attr_accessor
另外,要进一步回答您有关何时使用的问题attr_accessor
...
当您想要创建和存储与业务逻辑以及模型相关的信息并且仅在请求/实例生命周期期间持续时,您将使用它。
例如原始密码(尽管我对任何操纵原始密码的人感到畏缩)
或类似...
@stock.current_price
where@stock
是一个ActiveRecord::Base
对象,但是.current_price
在实例化@stock
对象时从 API 计算或检索,因为从数据库中持久化和检索不断变化的值(例如任何给定时间点的股票价格)是没有意义的。
推荐阅读
- java - 数组中两点之间的距离
- java - 使用 Eclipse-rcp Neon 构建的插件不适用于 Eclipse Photon
- kubernetes - 入口控制器 nginx 从 basic_auth 中排除 IP
- python - 带有 windows、libusb1 和 libusb-win32 后端的 PyUSB 无法正常工作
- ansible - Ansible 命令从远程服务器中提取文件并阻止(如果已经存在)
- vue.js - 使用 Vue.js 和 Amplify 的 Facebook 登录组件
- windows - VPN 与 PowerShell 连接在 Windows 服务中不起作用
- r - 如何在 r 中使用 for 循环引导矩阵?
- eiffel - 埃菲尔:更改继承特征的签名
- c# - 如何将 parsedArray 数据存储到 SQL Server 数据库?