Forum: Ruby on Rails ids writer fields for HABTM relationship.

Announcement (2017-05-07): is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see and for other Rails- und Ruby-related community platforms.
85a81dffca2b89b1d483691bbca8de3d?d=identicon&s=25 Pierre M. (pierre_m)
on 2012-11-03 02:43
Hello forum readers,

Let's say i have two models: Person and Role (i replicated the problem
with Post & Tag as well, as i thought the problem was linked to some
application-specific rights problem, but it wasn't).

In Person, attr_accessible role_ids is declared, so it accepts an array
of Role ids as an argument when creating / updating.

If i fire up the rails console and just do:
Person.first.role_ids = [1, 2, 3]
Everything works so far.

Now from the web browser, when trying to update a specific person, i
Started PUT "/people/1?_dc=1351904653950" for at 2012-11-02
18:04:13 -0700
Processing by PeopleController#update as JSON
  Parameters: {"email"=>"", "last_name"=>"DOE",
"first_name"=>"John", "company_id"=>1,
"updated_at"=>"2012-11-02T22:27:00Z", "role_ids"=>[2, 1], "id"=>"1",
"_dc"=>"1351904653950", "person"=>{"email"=>"",
"first_name"=>"John", "last_name"=>"DOE", "role_ids"=>[2, 1]}}
WARNING: Can't verify CSRF token authenticity
  Person Load (0.2ms)  SELECT "people".* FROM "people" WHERE
"people"."email" = '' LIMIT 1
  Role Load (0.1ms)  SELECT "roles".* FROM "roles" INNER JOIN
"people_roles" ON "roles"."id" = "people_roles"."role_id" WHERE
"people_roles"."person_id" = 1
  ModelRight Load (0.1ms)  SELECT "model_rights".* FROM "model_rights"
WHERE "model_rights"."role_id" IN (2, 1, 3)
  Company Load (4.5ms)  SELECT "companies".* FROM "companies" WHERE
"companies"."id" = ? LIMIT 1  [["id", 1]]
  Person Load (0.2ms)  SELECT "people".* FROM "people" WHERE
"people"."company_id" = 1 AND "people"."id" = ? LIMIT 1  [["id", "1"]]
   (0.1ms)  begin transaction
   (0.0ms)  rollback transaction
Completed 500 Internal Server Error in 2790ms
NoMethodError (undefined method `type_cast' for nil:NilClass):
  app/controllers/people_controller.rb:21:in `update'

I scratched my head for quite a long time before finding out that after
restarting the rails server, the error would disappear and the Person
would actually be updated...

So with the help of pry and pry-debugger, i have pinpointed the exact
source of the "NoMethodError" error (in collection_association.rb, at
line 69):
     # Implements the ids writer method, e.g. foo.item_ids= for
Foo.has_many :items
     def ids_writer(ids)
       pk_column = reflection.primary_key_column
       ids = Array.wrap(ids).reject { |id| id.blank? }! { |i| pk_column.type_cast(i) }
       replace(klass.find(ids).index_by { |r| }.values_at(*ids))
This method gets called by the People controller in the update action
(@person.update_attributes params[:person]), which in turn deeper in
Rail's guts arrive to the pinpointed method when accessing an *_ids

What is very weird, is that pk_column is nil (Hence the NoMethodError
error later), but when restarting the server and trying to output
pk_column, then it is a valid association column... Random behavior,
Later, the error will re-appear, and then will disappear if i restart
the server...

Is there anyone who would help me to understand what i'm doing wrong? Is
a *_ids writer field any different in an HABTM assotiation compared to a
regular HM association?

Thank you for your help!


[edit]Sorry, i forgot. i'm using Ruby 1.9.3p286 along with Rails 3.2.6
and other various gems. My operating system is Mac OSX Mountain Lion and
is up to date.[/edit]
This topic is locked and can not be replied to.