Migration
create_table :my_model do |t|
t.string :domain, null: false
t.string :category, null: false
t.string :name, null: false
MyModel
validates :name, presence: true, uniqueness: {scope:[:domain, :category]}
attr_accessor :name
このとき、MyModel.Create によって作成を試みると
ActiveRecord::NotNullViolation: SQLite3::ConstraintException: NOT NULL constraint failed:...
が起こる。
attr_accessor
attr_accessor :name
を除いてあげると、通るようになる。
明確な理由は分からないが、 attr_accessor は メソッド定義を上書きしている模様。
Rails API docs for Active Record によると
おそらく Overwriting default accessors にあるように、super する必要があるものの、attr_accessor 単体では super しないために値が保存されないのではないかと思われる。(確信なし)
どうすればいいか
attr_accessor でアクセスしない場合、name はローカル変数として扱われてしまい、同一モデル内では値が上書きされない。したがって作成・保存のときに Null となっている。
(ただしReadはできるのでややこしい)。
同一モデル内で属性(attributes)にアクセス(更新・上書き)したい場合は、
self を使う。
MyModel
def update_name
self.name = 'My Nickname'
end
など。
memo: Rails 5.2.3