rails3 default_scope, and default column value in migration
Asked Answered
F

2

10
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>

Fujio answered 20/10, 2010 at 6:10 Comment(0)
G
12

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

Graybeard answered 20/10, 2010 at 8:35 Comment(2)
+1. This documentation is actually absent in the older versions of API docs. I had to initially dig into to source to find out why is it happening so. (This means we must contribute more to docrails (github.com/lifo/docrails)Allene
I find this "feature" very annoying. I mean, what I want to search is completely unrelated to what I want to created.Solenoid
H
1

A little trick is to use

default_scope -> { where('crews.approved = 1') }
Heliport answered 26/5, 2016 at 8:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.