【发布时间】:2014-08-31 19:02:48
【问题描述】:
如果一个新主题不存在,我如何惯用地创建一个新主题,或者如果该主题存在,我如何创建与会议的关联?
我正在处理一个包含会议和主题的项目。它们都通过一个 ConferenceTopic 对象相互关联。主题的名称是唯一的。
下面是我在会议上创建的名为#find_or_create_topic_with 的自定义方法,它接受名称参数。我这样做是因为当我尝试在会议主题上命名 #find_or_create_by 时,我没有成功为第二个主题命名(下面的 Rails 控制台日志)
The commit for this kludge is on Github.
class Conference < ActiveRecord::Base
…
def find_or_create_topic_with(name)
if topic = Topic.find_by(name: name)
self.topics.include?(topic) ? topic : self.topics << topic
else
self.topics.create(name: name)
end
end
end
有关主题的 find_or_create_by 的 Rails 控制台日志
2.1.2 :001 > Conference.last.topics.find_or_create_by(name: "fun")
Conference Load (1.0ms) SELECT "conferences".* FROM "conferences" ORDER BY "conferences"."id" DESC LIMIT 1
Topic Load (0.5ms) SELECT "topics".* FROM "topics" INNER JOIN "conference_topics" ON "topics"."id" = "conference_topics"."topic_id" WHERE "conference_topics"."conference_id" = $1 AND "topics"."name" = 'fun' LIMIT 1 [["conference_id", 3]]
(0.1ms) BEGIN
Topic Exists (0.4ms) SELECT 1 AS one FROM "topics" WHERE "topics"."name" = 'fun' LIMIT 1
SQL (0.3ms) INSERT INTO "topics" ("created_at", "name", "updated_at") VALUES ($1, $2, $3) RETURNING "id" [["created_at", "2014-08-31 18:57:56.274109"], ["name", "fun"], ["updated_at", "2014-08-31 18:57:56.274109"]]
SQL (0.5ms) INSERT INTO "conference_topics" ("conference_id", "created_at", "topic_id", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id" [["conference_id", 3], ["created_at", "2014-08-31 18:57:56.287526"], ["topic_id", 8], ["updated_at", "2014-08-31 18:57:56.287526"]]
(2.1ms) COMMIT
=> #<Topic id: 8, name: "fun", created_at: "2014-08-31 18:57:56", updated_at: "2014-08-31 18:57:56">
2.1.2 :002 > Conference.first.topics.find_or_create_by(name: "fun")
Conference Load (0.6ms) SELECT "conferences".* FROM "conferences" ORDER BY "conferences"."id" ASC LIMIT 1
Topic Load (0.4ms) SELECT "topics".* FROM "topics" INNER JOIN "conference_topics" ON "topics"."id" = "conference_topics"."topic_id" WHERE "conference_topics"."conference_id" = $1 AND "topics"."name" = 'fun' LIMIT 1 [["conference_id", 1]]
(0.2ms) BEGIN
Topic Exists (0.3ms) SELECT 1 AS one FROM "topics" WHERE "topics"."name" = 'fun' LIMIT 1
(0.2ms) COMMIT
=> #<Topic id: nil, name: "fun", created_at: nil, updated_at: nil>
2.1.2 :003 > Conference.first.topics
Conference Load (0.5ms) SELECT "conferences".* FROM "conferences" ORDER BY "conferences"."id" ASC LIMIT 1
Topic Load (0.3ms) SELECT "topics".* FROM "topics" INNER JOIN "conference_topics" ON "topics"."id" = "conference_topics"."topic_id" WHERE "conference_topics"."conference_id" = $1 [["conference_id", 1]]
=> #<ActiveRecord::Associations::CollectionProxy [#<Topic id: 7, name: "ruby", created_at: "2014-08-31 18:40:40", updated_at: "2014-08-31 18:40:40">]>
以下是查找主题“有趣”的会议的日志
2.1.2 :015 > Topic.find_by(name: "fun").conferences
Topic Load (0.5ms) SELECT "topics".* FROM "topics" WHERE "topics"."name" = 'fun' LIMIT 1
Conference Load (0.3ms) SELECT "conferences".* FROM "conferences" INNER JOIN "conference_topics" ON "conferences"."id" = "conference_topics"."conference_id" WHERE "conference_topics"."topic_id" = $1 [["topic_id", 8]]
=> #<ActiveRecord::Associations::CollectionProxy [#<Conference id: 3, name: "TooLongDidn'tCareConf", location: "Boston", code_of_conduct: false, childcare: false, last_years_attendance: 0, created_at: "2014-08-31 17:47:35", updated_at: "2014-08-31 17:47:35">]>
2.1.2 :016 > Topic.find_by(name: "fun").conferences.count
Topic Load (0.5ms) SELECT "topics".* FROM "topics" WHERE "topics"."name" = 'fun' LIMIT 1
(0.3ms) SELECT COUNT(*) FROM "conferences" INNER JOIN "conference_topics" ON "conferences"."id" = "conference_topics"."conference_id" WHERE "conference_topics"."topic_id" = $1 [["topic_id", 8]]
=> 1
我希望集合代理同时包含第一次和最后一次会议,并且计数为 2。仅使用 #find_or_create_by 我只能将其与首次创建的会议相关联,而不是找到id 为 nil 的主题。
【问题讨论】:
标签: ruby-on-rails activerecord ruby-on-rails-4 rails-activerecord