使用 new() 与 create() 创建关联

Creating associations with new() versus create()

我希望这个问题能让我更多地了解如何使用没有继承 "Rails magic" 的外键构建多对多关系,因为我一直在谷歌搜索小时了还是没完全看懂。

基本上Users可以组织EventsEvents可以组织很多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' 时,您会得到一个空数组。