Bhawan
Bhawan

Reputation: 2491

value not setting with '=' in rails

Attached screenshot for the proofI 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

Answers (2)

max
max

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

Alex Wayne
Alex Wayne

Reputation: 187044

I think you are confusing Rails here.

  1. You have a column named modality_day on an Active Record model. This lets you read/write that property on instances of At::ModalityCombo.
  2. You also have 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

Related Questions