在Rails中,数值未使用’=’设置。

huangapple go评论72阅读模式
英文:

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?

英文:

在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?

答案1

得分: 3

I think you are confusing Rails here.

  1. 你在一个 Active Record 模型上有一个名为 modality_day 的列。这允许你在 At::ModalityCombo 的实例上读取/写入该属性。
  2. 你还为 modality_day 设置了 attr_readerattr_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.

  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.

答案2

得分: 0

attr_readerattr_writerattr_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.

huangapple
  • 本文由 发表于 2020年1月7日 02:18:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/59617005.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定