rails/rails — pull request #11535 by pftg (2013-07-21 15:53:23+00:00)
Title: Use association scope attributes over default attributes/scope [WIP]

In order to build/create associated objects with default attributes extracted from association scope neither use them from default scope/attributes if they has the same names.

Test case:

```ruby
unless File.exists?('Gemfile')
File.write('Gemfile', <<-GEMFILE)
source 'https://rubygems.org'
gem 'rails', '= 4.0.0'
gem 'sqlite3'
GEMFILE

system 'bundle'
end

require 'bundler'
Bundler.setup(:default)

require 'active_record'
require 'minitest/autorun'
require 'logger'

# This connection will do for database-independent bug reports.
ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: ':memory:')
ActiveRecord::Base.logger = Logger.new(STDOUT)

ActiveRecord::Schema.define do
create_table :posts do |t|
t.string :name
end

create_table :comments do |t|
t.string :author, default: 'Test'
t.integer :post_id
end
end

class Post < ActiveRecord::Base
has_many :comments
has_many :admin_comments, -> { where author: 'Admin' }, class_name: 'Comment'

end

class Comment < ActiveRecord::Base
belongs_to :post
end

class BugTest < MiniTest::Unit::TestCase
def test_association_stuff
post = Post.create
admin_comment = post.admin_comments.build

assert_equal 'Admin', admin_comment.author
end
end
```

For __master__ version this test case is failed.

Problem investigation:

by the order of attribute initialization we have:

1. Initializing default attributes from column: https://github.com/rails/rails/blob/master/activerecord/lib/active_record/core.rb#L171
2. Override column attributes by default scope attributes: https://github.com/rails/rails/blob/master/activerecord/lib/active_record/core.rb#L177
3. And only then invoking initializing of association related data: https://github.com/rails/rails/blob/master/activerecord/lib/active_record/associations/association.rb#L239
4. But https://github.com/rails/rails/blob/master/activerecord/lib/active_record/associations/association.rb#L164 in case to filter User defined attributes like `post.admin_comments.build(author: 'Another Admin')` there is `record.changed` which skip association scope attrbutes with same name with `default_scope` or default column attributes.

I'd like to move `initialize_attributes` before default attributes initialized or refactor it to override default attributes, but some other classes use it and need more time to investigate how to complete refactoring. In same time I need to ask, do we need this feature, should I continue refactoring of `build_record ` and `initialize_attributes`?

For now I added fast fix.

/cc @senny, @rafaelfranca, @carlosantoniodasilva