4

Why does this create method make a nil record?

I have tried:

Dropdown.create(subject: "test")

Dropdown.create({subject: "test", subject_value: "1"})

Dropdown.create({:subject => "test", :subject_value => "1"})

All result in nil records.

   (0.1ms)  begin transaction
  SQL (0.6ms)  INSERT INTO "dropdowns" ("created_at", "updated_at") VALUES (?, ?)  [["created_at", "2016-01-21 23:58:04.979225"], ["updated_at", "2016-01-21 23:58:04.979225"]]
   (2.1ms)  commit transaction
=> #<Dropdown id: 145, subject: nil, visible: nil, subject_value: nil, subject_description: nil, created_at: "2016-01-21 23:58:04", updated_at: "2016-01-21 23:58:04

Model file

class Dropdown < ActiveRecord::Base
  
    FIELDS =  [
              :subject,
              :visible,
              :subject_value,
              :subject_description
            ]
  
  attr_accessor(*FIELDS)
  subjects = %w[math english spanish]
  
  subjects.each do |s|
    scope s.to_sym, -> { where(subject: s) }
  end

end

Migration file

class CreateDropdowns < ActiveRecord::Migration
  def change
    create_table :dropdowns do |t|
      t.string :subject
      t.boolean :visible
      t.string :subject_value
      t.string :subject_description

      t.timestamps null: false
    end
  end
end
Community
  • 1
  • 1
user2012677
  • 5,465
  • 6
  • 51
  • 113
  • 2
    you probably don't want `attr_accessor(*FIELDS)` in your model, you are looking for the wrath of ActiveRecord – bjhaid Jan 22 '16 at 02:25
  • 2
    see https://stackoverflow.com/questions/4700785/using-attr-accessor-and-attr-accessible-on-the-same-field#answer-4735726 and https://stackoverflow.com/questions/2793098/usage-of-attr-accessor-in-rails – bjhaid Jan 22 '16 at 02:49

2 Answers2

2

You're overriding your ActiveRecord::Base functionality by declaring attr_accessor:

#app/models/dropdown.rb
class Dropdown < ActiveRecord::Base

  subjects = %w(math english spanish)

  subjects.each do |s|
    scope s.to_sym, -> { where(subject: s) }
  end

end
  1. You don't need to declare FIELDS -- you can call @model.attributes (instance) or Model.column_names (class) to get all the fields for that model.

  2. attr_accessor creates a set of getter/setter methods in the class. This overrides any attributes you may have from your db, which is why you're getting nil entries when you save. Good ref here.

--

The above model should work for you.

Community
  • 1
  • 1
Richard Peck
  • 76,116
  • 9
  • 93
  • 147
-1

It is not necessary to use attr_accessor if these fields are columns of a table in your database. ActiveRecord done it for you.

Try to use attr_accessible instead of attr_accessor. But for rails 4+, not necessary to use it. see http://apidock.com/rails/ActiveModel/MassAssignmentSecurity/ClassMethods/attr_accessible

This method is deprecated or moved on the latest stable version. The last existing version (v3.2.13) is shown here.

Long Nguyen
  • 373
  • 2
  • 9