class CreateCrews < ActiveRecord::Migration
def self.up
create_table :crews do |t|
t.string :title
t.text :description
t.boolean :adult
t.boolean :private
t.integer :gender_id
t.boolean :approved, :default => false
t.timestamps
end
end
def self.down
drop_table :crews
end
end
class Crew < ActiveRecord::Base
has_many :users, :through => :crew_users
belongs_to :user
default_scope where(:approved => true)
end
When I go to console, and create a new record, the "approved" property is set to true, why ?
How I can set it automatically to the default value (false) like shown in my migration file ?
wojciech@vostro:~/work/ze$ rails console
Loading development environment (Rails 3.0.0)
ruby-1.9.2-p0 > c = Crew.new
=> #<Crew id: nil, title: nil, description: nil, adult: nil, private: nil, gender_id: nil, approved: true, created_at: nil, updated_at: nil, logo_file_name: nil, logo_content_type: nil, logo_file_size: nil, logo_updated_at: nil>
In Ruby on Rails, you can set default values for attributes in the database by including them as part of your migration. The syntax is default: 'value' . This is useful if you want to define lots of attributes at once, and it's easy to see what the default value is at a glance when looking at your db/schema.
Internally Rails only uses the migration's number (the timestamp) to identify them. Prior to Rails 2.1 the migration number started at 1 and was incremented each time a migration was generated. With multiple developers it was easy for these to clash requiring you to rollback migrations and renumber them.
When you run rails db:migrate, the up method is executed, whereas rails db:rollback executes the down method. Simply, up runs the migration, down rolls the migration back.
just use rake db:reset , that will drop your database (same as undoing all migrations) and reset to the last schema. UPDATE: a more correct approach will be using rake db:migrate:reset . That will drop the database, create it again and run all the migrations, instead of resetting to the latest schema.
The documentation fordefault_scope
says that the provided scope is applied to both queries and new objects. Default values supplied at the model level will always take precedence over defaults provided at the schema level because they are made inside the application before the data is ever sent to the database.
You can use unscoped
to temporarily skip all scoping (including the default_scope
). This should allow the lower level database defaulting mechanism to take effect*.
Crew.unscoped.new
*ActiveRecord obscures the difference between defaulting defined in the database (schema) and defaulting done in the application (model). During initialization, it parses the database schema and notes any default values specified there. Later, when creating objects, it assigns those schema-specified default values without touching the database. For example, you will see approved: false
(instead of approved: nil
) in the result of Crew.unscoped.new
even though the data has never been sent to the database to get it to fill in its default value (ActiveRecord preemptively fills in the default value based on information it pulled out of the schema).
A little trick is to use
default_scope -> { where('crews.approved = 1') }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With