Ruby on Rails
Thursday, January 12, 2012
On Thu, Jan 12, 2012 at 5:02 PM, Mauro <mrsanna1@gmail.com> wrote:
-- Here are params:
{"utf8"=>"✓", "authenticity_token"=>"RpOtdQMIm6B45/e91h6ljXKpMCtRD//QJ+bP4knrcic=",
"manager"=>{"name"=>"q", "surname"=>"",
"fiscal_code"=>"1121111111111111", "city"=>"", "zip_code"=>"",
"address"=>"", "street_number"=>"", "tel"=>"", "email"=>""},
"commit"=>"Crea Amministratore", "action"=>"create",
"controller"=>"managers", "company_id"=>"6"}
Started POST "/companies/6/managers" for 0:0:0:0:0:0:0:1 at 2012-01-12
16:58:49 +0100
Processing by ManagersController#create as JS
Parameters: {"utf8"=>"✓",
"authenticity_token"=>"RpOtdQMIm6B45/e91h6ljXKpMCtRD//QJ+bP4knrcic=",
"manager"=>{"name"=>"q", "surname"=>"",
"fiscal_code"=>"1121111111111111", "city"=>"", "zip_code"=>"",
"address"=>"", "street_number"=>"", "tel"=>"", "email"=>""},
"commit"=>"Crea Amministratore", "company_id"=>"6"}
As you see i have company_id => but the association is not created, is
created only a new Manager but with no Company association.
You are correct (and I learned something). In this many_to_many association
a build and a later save on the newly build object, seems to NOT create
the intermediate association object in the database ... (this works as I would
expect in a straight has_many, but seemingly not in a has_many :through ...).
Using a 'create' resolves that problem, but that means you cannot delay the
saving to database to one consolidated save at the end, as I prefer to do.
Some code:
002:0> Company.create
SQL (11.6ms) INSERT INTO "companies" ("created_at", "updated_at") VALUES (?, ?) [["created_at", Thu, 12 Jan 2012 23:28:57 UTC +00:00], ["updated_at", Thu, 12 Jan 2012 23:28:57 UTC +00:00]]
004:0> @company = Company.find(1)
Company Load (0.2ms) SELECT "companies".* FROM "companies" WHERE "companies"."id" = ? LIMIT 1 [["id", 1]]
=> #<Company id: 1, created_at: "2012-01-12 23:28:57", updated_at: "2012-01-12 23:28:57">
006:0> @manager = @company.managers.build()
=> #<Manager id: nil, created_at: nil, updated_at: nil>
007:0> @manager.save!
SQL (0.6ms) INSERT INTO "managers" ("created_at", "updated_at") VALUES (?, ?) [["created_at", Thu, 12 Jan 2012 23:30:25 UTC +00:00], ["updated_at", Thu, 12 Jan 2012 23:30:25 UTC +00:00]]
=> true
## This does NOT save the intermediate management record :-(
008:0> @manager = @company.managers.create()
SQL (0.5ms) INSERT INTO "managers" ("created_at", "updated_at") VALUES (?, ?) [["created_at", Thu, 12 Jan 2012 23:30:42 UTC +00:00], ["updated_at", Thu, 12 Jan 2012 23:30:42 UTC +00:00]]
SQL (0.8ms) INSERT INTO "managements" ("company_id", "created_at", "manager_id", "role", "updated_at") VALUES (?, ?, ?, ?, ?) [["company_id", 1], ["created_at", Thu, 12 Jan 2012 23:30:42 UTC +00:00], ["manager_id", 2], ["role", nil], ["updated_at", Thu, 12 Jan 2012 23:30:42 UTC +00:00]]
=> #<Manager id: 2, created_at: "2012-01-12 23:30:42", updated_at: "2012-01-12 23:30:42">
## but this does save the intermediate management record :-)
009:0> @manager.managements.first
Management Load (0.3ms) SELECT "managements".* FROM "managements" WHERE "managements"."manager_id" = 2 LIMIT 1
=> #<Management id: 1, company_id: 1, manager_id: 2, role: nil, created_at: "2012-01-12 23:30:42", updated_at: "2012-01-12 23:30:42">
010:0> @manager.managements.first.role = "test role"
Management Load (0.3ms) SELECT "managements".* FROM "managements" WHERE "managements"."manager_id" = 2 LIMIT 1
=> "test role"
## Huh, Y U Reload ? (this is a different problem)
011:0> @manager.managements.first.save!
Management Load (0.3ms) SELECT "managements".* FROM "managements" WHERE "managements"."manager_id" = 2 LIMIT 1
=> true
## Huh, Y U Reload again ... and now save a pristine management record without my role assigned ?
## I could not reproduce this behavior ... never seen this before.
013:0> management = @manager.managements.first
Management Load (0.3ms) SELECT "managements".* FROM "managements" WHERE "managements"."manager_id" = 2 LIMIT 1
=> #<Management id: 1, company_id: 1, manager_id: 2, role: nil, created_at: "2012-01-12 23:30:42", updated_at: "2012-01-12 23:30:42">
014:0> management.role = "test role"
=> "test role"
015:0> management.save!
(0.4ms) UPDATE "managements" SET "role" = 'test role', "updated_at" = '2012-01-12 23:32:24.704538' WHERE "managements"."id" = 1
=> true
# forcing management to be the same record
017:0> @manager.managements.first
Management Load (0.3ms) SELECT "managements".* FROM "managements" WHERE "managements"."manager_id" = 2 LIMIT 1
=> #<Management id: 1, company_id: 1, manager_id: 2, role: "test role", created_at: "2012-01-12 23:30:42", updated_at: "2012-01-12 23:32:24">
018:0> @manager.managements.first.role
Management Load (0.3ms) SELECT "managements".* FROM "managements" WHERE "managements"."manager_id" = 2 LIMIT 1
=> "test role"
And now, reading it back from the database yields the role.
Please not that the use of "first" here is dangerous, unless you make sure there is never
a double association record between the same combination of Company and Manager.
Another problem, I do not see the "role" value anywhere in your params, so probably also
the form needs fixing somewhere ?
HTH,
Peter
Peter Vandenabeele
http://twitter.com/peter_v
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group.
To post to this group, send email to rubyonrails-talk@googlegroups.com.
To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment