rails/rails — Issue #4570: Building has_many association failed with rails 3.2.0!
Author: NoICE
Created: 2012-01-21 08:50:52+00:00
State: open

Ruby 1.9.3, Rails 3.2.0, mysql2 0.3.11

I've migrated one app from rails 3.0.11 to 3.2.0 and it fails to fill the association column (in this case `mrl_message_id`) when building new row:

``` ruby
# relevant parts only...
class User::Message < ActiveRecord::Base
self.table_name = :user_tbl_message
self.primary_key = :m_id

has_many :read_logs, :foreign_key => :mrl_message_id, :class_name => 'User::MessageReadLog'
# ...

# marks this message as read for given user, with given state_id
def mark_read_by(user, state_id)
state_id = 1 unless [1, 2].include?(state_id.to_i)
rl = self.read_logs.where(:mrl_user_id => user.u_id).first
# ISSUE: this line fails, mrl_message_id is nil
rl = self.read_logs.build(:user => user) if rl.blank?
rl.mrl_status = state_id
# THIS LINE CRASHES now on 3.2 (because mrl_message_id is nil)
rl.save
true
end

end

# this class is complete as-is
class User::MessageReadLog < ActiveRecord::Base
self.table_name = :user_tbl_message_read_log
self.primary_key = :mrl_id

belongs_to :user, :foreign_key => :mrl_user_id, :class_name => 'User::User'
belongs_to :message, :foreign_key => :mrl_message_id, :class_name => 'User::Message'

end
```

this results in:

```
Mysql2::Error: Column 'mrl_message_id' cannot be null: INSERT INTO `user_tbl_message_read_log` (`created_at`, `mrl_message_id`, `mrl_status`, `mrl_user_id`, `updated_at`) VALUES ('2012-01-21 08:37:01', NULL, NULL, 1, '2012-01-21 08:37:01')
```

debug:

```

1.9.3p0 :032 > a = User::Message.find 5
User::Message Load (0.1ms) SELECT `user_tbl_message`.* FROM `user_tbl_message` WHERE `user_tbl_message`.`m_id` = 5 LIMIT 1

=> #
1.9.3p0 :033 > mrl = a.read_logs.build user: User::User.first
User::User Load (0.1ms) SELECT `user_tbl_user`.* FROM `user_tbl_user` LIMIT 1
=> #

# mrl_message_id is NIL:

1.9.3p0 :034 > mrl.inspect
=> "#"

1.9.3p0 :035 > mrl.save
(0.3ms) BEGIN
SQL (0.4ms) INSERT INTO `user_tbl_message_read_log` (`created_at`, `mrl_message_id`, `mrl_status`, `mrl_user_id`, `updated_at`) VALUES ('2012-01-21 08:38:55', NULL, NULL, 1, '2012-01-21 08:38:55')
(0.1ms) ROLLBACK
ActiveRecord::StatementInvalid: Mysql2::Error: Column 'mrl_message_id' cannot be null: INSERT INTO `user_tbl_message_read_log` (`created_at`, `mrl_message_id`, `mrl_status`, `mrl_user_id`, `updated_at`) VALUES ('2012-01-21 08:38:55', NULL, NULL, 1, '2012-01-21 08:38:55')

# proof that the association is defined well... (reading the rows works, i.e. generates proper SQL):
1.9.3p0 :037 > a.read_logs
User::MessageReadLog Load (0.1ms) SELECT `user_tbl_message_read_log`.* FROM `user_tbl_message_read_log` WHERE `user_tbl_message_read_log`.`mrl_message_id` = 5
=> []
```

This worked well on Rails 3.0.11 and I know there were lots of changes around association proxies, but this is a bug or am I doing something wrong? (what's also funny is this worked on 3.0.11 even with `.new` instead of `.build` and now doesn't work either)

Adding SQL create table syntax for the sake of complete report:

``` sql
CREATE TABLE `user_tbl_message_read_log` (
`mrl_id` int(11) NOT NULL AUTO_INCREMENT,
`mrl_message_id` int(11) NOT NULL,
`mrl_user_id` int(11) NOT NULL,
`mrl_status` int(11) NOT NULL,
`created_at` datetime DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
PRIMARY KEY (`mrl_id`)
) ENGINE=InnoDB AUTO_INCREMENT=40234 DEFAULT CHARSET=utf8;
```

What can I do to help you track this bug down?