Reputation: 2491
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?
Upvotes: 1
Views: 132
Reputation: 102055
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.
Upvotes: 0
Reputation: 187044
I think you are confusing Rails here.
modality_day
on an Active Record model. This lets you read/write that property on instances of At::ModalityCombo
.attr_reader
and attr_writer
setup for modality_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.
Upvotes: 3