英文:
value not setting with '=' in rails
问题
I have a model which looks something like this:
class At::ModalityCombo < Base
self.table_name = 'at_modalites_at_combos'
belongs_to :at_modality, :class_name => 'At::Modality', foreign_key: :modality_id
belongs_to :at_combo, :class_name => 'At::Combo', foreign_key: :combo_id
attr_reader :modality_day
attr_writer :modality_day
end
Migration for modality_day
column is like:
class AddDayInModalityCombo < ActiveRecord::Migration[5.2]
def up
add_column :at_modalites_at_combos, :modality_day, :integer, default: 0
end
def down
remove_column :at_modalites_at_combos, :modality_day
end
end
On rails console,
abc = At::ModalityCombo.new
abc.modality_day = 4
abc
Output:
modality_id: nil, combo_id: nil, modality_day: 0
Why modality_day is still 0?
英文:
I have a model which looks something like this:
class At::ModalityCombo < Base
self.table_name = 'at_modalites_at_combos'
belongs_to :at_modality, :class_name => 'At::Modality', foreign_key: :modality_id
belongs_to :at_combo, :class_name => 'At::Combo', foreign_key: :combo_id
attr_reader :modality_day
attr_writer :modality_day
end
Migration for modality_day
column is like:
class AddDayInModalityCombo < ActiveRecord::Migration[5.2]
def up
add_column :at_modalites_at_combos, :modality_day, :integer, default: 0
end
def down
remove_column :at_modalites_at_combos, :modality_day
end
end
On rails console,
abc = At::ModalityCombo.new
abc.modality_day = 4
abc
Output:
modality_id: nil, combo_id: nil, modality_day: 0
Why modality_day is still 0?
答案1
得分: 3
I think you are confusing Rails here.
- 你在一个 Active Record 模型上有一个名为
modality_day
的列。这允许你在At::ModalityCombo
的实例上读取/写入该属性。 - 你还为
modality_day
设置了attr_reader
和attr_writer
。
看起来 attr_writer/attr_reader
正在覆盖了通常用于管理数据库中定义的属性的方法。删除它们应该解决这个问题,使其按照你的预期工作。
attr_reader :modality_day
基本上等同于:
def modality_day
@modality_day
end
而 attr_writer :modality_day
基本上等同于:
def modality_day=(value)
@modality_day = value
end
这些方法管理一个实例变量,但 Active Record 不以相同的方式存储你的数据库数据。
英文:
I think you are confusing Rails here.
- You have a column named
modality_day
on an Active Record model. This lets you read/write that property on instances ofAt::ModalityCombo
. - You also have
attr_reader
andattr_writer
setup formodality_day
.
It looks like attr_writer/attr_reader is overriding the methods that would normally let you manage the property defined in your database. Deleting those should fix this and make it work like you expect.
attr_reader :modality_day
is basically equivalent to:
def modality_day
@modality_day
end
And attr_writer :modality_day
is basically equivalent to:
def modality_day=(value)
@modality_day = value
end
These methods manage an instance variable, but Active Record does not store your database data in this same way.
答案2
得分: 0
attr_reader
、attr_writer
和attr_accessor
不应该在Rails模型中使用(至少在Rails 5.0+中不应该使用)。它们是Ruby内置的元编程方法,用于创建setter和getter。
ActiveRecord实际上直接从数据库中读取模式,并创建与数据库表中的列相对应的特殊setter和getter。这些setter远远超越了基本的attr_writer
setter - 它们进行了类型转换、脏数据跟踪等操作。
如果你使用attr_accessor
,你会覆盖setter,你的模型将停止将属性持久化到数据库,等等。
对于不保存到数据库的"虚拟属性",请使用属性API,它提供了默认值和类型转换功能。
英文:
attr_reader
, attr_writer
and attr_accessor
should not be used in Rails models at all (at least not in Rails 5.0+). They are Rubys built in metaprogramming methods for creating setters and getters.
ActiveRecord actually reads the schema straight from the db and creates special setters and getters corresponding to the columns in the db table. These setters are light years from the basic attr_writer
setter - they do type casting, dirty tracking etc.
If you use attr_accessor
you overwrite the setter and your model will stop persisting the attribute among other things.
For "virtual attributes" that are not saved to the database use the attributes api which does default values and typecasting.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论