0

Rails 4. I got an Authentication model

class Authentication < ActiveRecord::Base
  ...
  has_and_belongs_to_many :posting_groups
  ...
end

and a PostingGroup model

class PostingGroup < ActiveRecord::Base
  ...
  has_and_belongs_to_many :authentications
  ...
end

The migration for the join table look like this:

def change
  create_table :authentications_posting_groups, id: false do |t|
    t.belongs_to :posting_group
    t.belongs_to :authentication
  end
end

Neither the Authentication nor the PostingGroup tables need references to each other or to the join table, so there's no relevant information in them. When updating the PostingGroups of an Authentication I do the following:

def update
  @authentication.update_attributes(authentication_params)
end
def authentication_params
    params.require(:other_unimportant_stuff, posting_groups: [])
end

During the execution of the update action, params is as follows:

{"authentication"=>{"posting_groups"=>["17", "18"]}, "stuff"=>"more stuff}

...where, 17 and 18 are the ids of the posting groups which should be saved. And, indeed, the @authentication variable in update contains the desired PostingGroups and update_attributes returns true. However, Authentication.find(id).posting_groups (i.e. what actually was stored in the db) returns an empty set. Additionally, checking the authentications_posting_groups table shows the following:

posting_group_id    authentication_id   
              17    NULL
              18    NULL

For some weird reason the authentication_id is never making it to the db, which is funny because the save was triggered on this object in the first place. It's not the first time I encounter this problem but rather the second, the first time we noticed that everything worked fine (that is, those NULL didn't pop up in the db) when creating what in this scenario is the Authentication, but the same happened on update. On that occasion a hack was implemented re-creating the object (on create everything is OK!!), but here that's not an option. I'd immensely appreciate any pointers because this is driving us mad. Thanks.

Edit - here's the form which is triggering the whole thing:

= form_for authentication, remote: true do |f|
  = f.select :posting_groups, options_for_select(@posting_groups.map {|pg| [ pg.name, pg.id ] }), {}, multiple: true, class: "form-control posting_groups_select"
Simone Carletti
  • 173,507
  • 49
  • 363
  • 364
Carlos Romero
  • 698
  • 8
  • 18

2 Answers2

1

You should permit posting_group_ids and pass posting_group_ids

Controller

def update
  @authentication.update_attributes(authentication_params)
end
def authentication_params
    params.require(:other_unimportant_stuff, posting_group_ids: [])
end

View

= form_for authentication, remote: true do |f|
  = f.select :posting_group_ids, options_for_select(@posting_groups.map {|pg| [ pg.name, pg.id ] }), {}, multiple: true, class: "form-control posting_groups_select"
Nermin
  • 6,118
  • 13
  • 23
  • Tried this as well...same behaviour. Authentication_id in join table is NULL. – Carlos Romero Nov 28 '14 at 12:24
  • Have you tried to check if authentication has those posting_groups or if particular posting_group has authentication, maybe you are not looking the right way to the table data. Try open rails console and check if data is added? – Nermin Nov 28 '14 at 12:32
  • Yep I did, the join table is actually filled out, only with authentication_id set to null (therefore authentication.posting_groups is an empty set, as is posting_group.authentications) – Carlos Romero Nov 28 '14 at 12:34
  • Also, Authentication.new(posting_groups: [PostingGroup.find(1)]).save works perfectly (that is, the join table has both fields filled out). Updating it results in a null in authentication_id. WTF? – Carlos Romero Nov 28 '14 at 12:40
  • try to use update! to see if some errors get generated – Nermin Nov 28 '14 at 12:47
  • Mysql2::Error: Field 'authentication_id' doesn't have a default value: INSERT INTO `authentications_posting_groups` (`posting_group_id`) VALUES (2) same old story. authentication_id does not reach the db – Carlos Romero Nov 28 '14 at 12:49
  • I changed the has_and_belongs_to_many to a has_many :through. Same results. Seriously... – Carlos Romero Nov 28 '14 at 13:19
  • I really can't think what is the problem, it seems like object '@authentication' those not have id, is that even possible? You saw it generated error no default value for authentication_id when you used update! method. – Nermin Nov 28 '14 at 13:40
  • no no, it definitely has an id (I'm working with already persisted objects, therefore the problem - it's an update). I solved this by executing raw sql commands, mimicking what rails should do...dirty, but I need to push this forward. – Carlos Romero Nov 28 '14 at 13:49
0
params.require(:other_unimportant_stuff, posting_group_ids: [])

Notice the ids.

You're passing in posting_group_ids as per your params but your parameters are set to posting_groups so strong parameters will filter it out.

j-dexx
  • 10,286
  • 3
  • 23
  • 36
  • sorry! that was a typo, I've been trying some different approaches and that was one of them. It should be posting_groups: [] and I'm updating my question. – Carlos Romero Nov 28 '14 at 11:40