使用 new() 与 create() 创建关联
Creating associations with new() versus create()
我希望这个问题能让我更多地了解如何使用没有继承 "Rails magic" 的外键构建多对多关系,因为我一直在谷歌搜索小时了还是没完全看懂。
基本上Users
可以组织Events
,Events
可以组织很多Users
。
我有以下型号:
class User < ActiveRecord::Base
has_many :event_organizers, foreign_key: "organizer_id"
has_many :organized_events, through: :event_organizers, source: "event"
class EventOrganizer < ActiveRecord::Base
belongs_to :event
belongs_to :organizer, class_name: "User", foreign_key: "organizer_id"
class Event < ActiveRecord::Base
has_many :event_organizers
has_many :organizers, through: :event_organizers
如果您对 event_organizers
上的列有疑问:
event_organizers
event_id (references an event)
organizer_id (references a user)
现在是有趣的部分,我注意到它发生在我的控制器中,但会显示在控制台中以缩短 post:
2.2.0 :001 > User.first
User Load (0.1ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT 1
=> #<User id: 1, email: "test@test.com", password_digest: "a$SCOFgQTF4krBYlqKVHSSMOtVP8ad/vTFPN/60WjX8s....", first_name: "test", last_name: "user", admin: false, created_at: "2015-06-18 02:36:21", updated_at: "2015-06-18 02:36:21">
2.2.0 :002 > event = User.first.organized_events.new( name: "test", location: "test", start_time: Time.now, end_time: 2.hours.from_now )
User Load (0.2ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT 1
=> #<Event id: nil, name: "test", location: "test", start_time: "2015-06-18 02:37:15", end_time: "2015-06-18 04:37:15", created_at: nil, updated_at: nil>
2.2.0 :003 > event.organizers
=> #<ActiveRecord::Associations::CollectionProxy []>
2.2.0 :004 > event = User.first.organized_events.create( name: "test", location: "test", start_time: Time.now, end_time: 2.hours.from_now )
User Load (0.5ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT 1
(0.2ms) begin transaction
SQL (0.3ms) INSERT INTO "events" ("name", "location", "start_time", "end_time", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?) [["name", "test"], ["location", "test"], ["start_time", "2015-06-18 02:37:37.781981"], ["end_time", "2015-06-18 04:37:37.782003"], ["created_at", "2015-06-18 02:37:37.788761"], ["updated_at", "2015-06-18 02:37:37.788761"]]
User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 1]]
EventOrganizer Exists (0.1ms) SELECT 1 AS one FROM "event_organizers" WHERE ("event_organizers"."organizer_id" = 1 AND "event_organizers"."event_id" = 1) LIMIT 1
SQL (0.1ms) INSERT INTO "event_organizers" ("organizer_id", "event_id", "created_at", "updated_at") VALUES (?, ?, ?, ?) [["organizer_id", 1], ["event_id", 1], ["created_at", "2015-06-18 02:37:37.800400"], ["updated_at", "2015-06-18 02:37:37.800400"]]
(37.2ms) commit transaction
=> #<Event id: 1, name: "test", location: "test", start_time: "2015-06-18 02:37:37", end_time: "2015-06-18 04:37:37", created_at: "2015-06-18 02:37:37", updated_at: "2015-06-18 02:37:37">
2.2.0 :005 > event.organizers
User Load (0.6ms) SELECT "users".* FROM "users" INNER JOIN "event_organizers" ON "users"."id" = "event_organizers"."organizer_id" WHERE "event_organizers"."event_id" = ? [["event_id", 1]]
=> #<ActiveRecord::Associations::CollectionProxy [#<User id: 1, email: "test@test.com", password_digest: "a$SCOFgQTF4krBYlqKVHSSMOtVP8ad/vTFPN/60WjX8s....", first_name: "test", last_name: "user", admin: false, created_at: "2015-06-18 02:36:21", updated_at: "2015-06-18 02:36:21">]>
所以,我的问题是:为什么当我使用 user.organized_events.new()
时关联不存在,但是当我使用 user.organized_events.create()
时关联却存在?
是我的错。我应该更仔细地阅读你的问题。
您正在使用 event.organizers。我想这是因为你必须在你的模型中设置 inverse_of。
您会注意到,当您使用 'new' 时,不会生成新事件的 ID。记录的 ID 仅在将其保存到数据库时生成,并且仅当您未明确提及任何其他属性时,两条记录才通过其 ID 链接。由于尚未为新事件生成任何 ID,因此无法将用户链接到它。因此,当您使用查询 'event.organizers' 时,您会得到一个空数组。
我希望这个问题能让我更多地了解如何使用没有继承 "Rails magic" 的外键构建多对多关系,因为我一直在谷歌搜索小时了还是没完全看懂。
基本上Users
可以组织Events
,Events
可以组织很多Users
。
我有以下型号:
class User < ActiveRecord::Base
has_many :event_organizers, foreign_key: "organizer_id"
has_many :organized_events, through: :event_organizers, source: "event"
class EventOrganizer < ActiveRecord::Base
belongs_to :event
belongs_to :organizer, class_name: "User", foreign_key: "organizer_id"
class Event < ActiveRecord::Base
has_many :event_organizers
has_many :organizers, through: :event_organizers
如果您对 event_organizers
上的列有疑问:
event_organizers
event_id (references an event)
organizer_id (references a user)
现在是有趣的部分,我注意到它发生在我的控制器中,但会显示在控制台中以缩短 post:
2.2.0 :001 > User.first
User Load (0.1ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT 1
=> #<User id: 1, email: "test@test.com", password_digest: "a$SCOFgQTF4krBYlqKVHSSMOtVP8ad/vTFPN/60WjX8s....", first_name: "test", last_name: "user", admin: false, created_at: "2015-06-18 02:36:21", updated_at: "2015-06-18 02:36:21">
2.2.0 :002 > event = User.first.organized_events.new( name: "test", location: "test", start_time: Time.now, end_time: 2.hours.from_now )
User Load (0.2ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT 1
=> #<Event id: nil, name: "test", location: "test", start_time: "2015-06-18 02:37:15", end_time: "2015-06-18 04:37:15", created_at: nil, updated_at: nil>
2.2.0 :003 > event.organizers
=> #<ActiveRecord::Associations::CollectionProxy []>
2.2.0 :004 > event = User.first.organized_events.create( name: "test", location: "test", start_time: Time.now, end_time: 2.hours.from_now )
User Load (0.5ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT 1
(0.2ms) begin transaction
SQL (0.3ms) INSERT INTO "events" ("name", "location", "start_time", "end_time", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?) [["name", "test"], ["location", "test"], ["start_time", "2015-06-18 02:37:37.781981"], ["end_time", "2015-06-18 04:37:37.782003"], ["created_at", "2015-06-18 02:37:37.788761"], ["updated_at", "2015-06-18 02:37:37.788761"]]
User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 1]]
EventOrganizer Exists (0.1ms) SELECT 1 AS one FROM "event_organizers" WHERE ("event_organizers"."organizer_id" = 1 AND "event_organizers"."event_id" = 1) LIMIT 1
SQL (0.1ms) INSERT INTO "event_organizers" ("organizer_id", "event_id", "created_at", "updated_at") VALUES (?, ?, ?, ?) [["organizer_id", 1], ["event_id", 1], ["created_at", "2015-06-18 02:37:37.800400"], ["updated_at", "2015-06-18 02:37:37.800400"]]
(37.2ms) commit transaction
=> #<Event id: 1, name: "test", location: "test", start_time: "2015-06-18 02:37:37", end_time: "2015-06-18 04:37:37", created_at: "2015-06-18 02:37:37", updated_at: "2015-06-18 02:37:37">
2.2.0 :005 > event.organizers
User Load (0.6ms) SELECT "users".* FROM "users" INNER JOIN "event_organizers" ON "users"."id" = "event_organizers"."organizer_id" WHERE "event_organizers"."event_id" = ? [["event_id", 1]]
=> #<ActiveRecord::Associations::CollectionProxy [#<User id: 1, email: "test@test.com", password_digest: "a$SCOFgQTF4krBYlqKVHSSMOtVP8ad/vTFPN/60WjX8s....", first_name: "test", last_name: "user", admin: false, created_at: "2015-06-18 02:36:21", updated_at: "2015-06-18 02:36:21">]>
所以,我的问题是:为什么当我使用 user.organized_events.new()
时关联不存在,但是当我使用 user.organized_events.create()
时关联却存在?
是我的错。我应该更仔细地阅读你的问题。
您正在使用 event.organizers。我想这是因为你必须在你的模型中设置 inverse_of。
您会注意到,当您使用 'new' 时,不会生成新事件的 ID。记录的 ID 仅在将其保存到数据库时生成,并且仅当您未明确提及任何其他属性时,两条记录才通过其 ID 链接。由于尚未为新事件生成任何 ID,因此无法将用户链接到它。因此,当您使用查询 'event.organizers' 时,您会得到一个空数组。