虽然在列中存储多个值很诱人,但最终总会有人受伤。你最好建立一个连接表来关联模型。
例如你可以这样做:
class DiscussionThread < ActiveRecord::Base
has_many :participations
has_many :participants, :through => :participations
end
class Participation < ActiveRecord::Base
belongs_to :discussion_thread
belongs_to :participant, :class_name => "User", :foreign_key => :user_id
end
class User < ActiveRecord::Base
has_many :participations
has_many :dicussion_threads, :through => :participations
end
这给了你三个表:
table: discussion_threads
columns: id
table: participations
columns: id | discussion_thread_id | user_id
table: users
columns: id
要查找用户参与的线程,只需执行以下操作:
@user.discussion_threads
并找到参与线程的用户:
@discussion_thread.participants
注意:Thread 是 Ruby 中的保留字,所以我将其重命名为 DiscussionThread
编辑
介意展示一个如何序列化 id 数组然后查询它们的示例吗?
你在半夜醒来,在一种奇怪的冲动的力量下,你走到你的电脑前并创建了这个迁移:
rails g model Abomination horror_ids:text
和型号:
class Abomination < ActiveRecord::Base
serialize :horror_ids
end
你测试它以确保它可以存储一个数组:
@abomination = Abomination.create(:horror_ids=>[2,33,42])
@abomination.horror_ids # => [2,33,42]
那又怎样?你知道 Rails 在后台将其转换为 YAML,如下所示:
---\n
- 2\n
- 33\n
- 42\n
再次被那种奇怪的敦促所驱使,您想知道“我如何搜索存储在此列中的特定 id?”。好吧,它只是一个字符串,对吧?您知道如何在文本字段中找到它:
cthulhu = 33
Abomination.where(["horror_ids LIKE '%- ?\n%'",cthulhu]).first
随着恐惧的增加,您意识到有人可能会偶然发现这一点,并认为这实际上是一个好主意。它必须被摧毁!但你无法输入rm -rf *,而是奇怪的力量让你想到未来克苏鲁的盲目追随者开发者可能需要知道的怪癖,例如
@abomination = Abomination.create
@abomination.horror_ids # => nil
@abomination = Abomination.create(:horror_ids=>[])
@abomination.horror_ids # => []
@abomination = Abomination.create(:horror_ids=>"any string value can go here")
@abomination.horror_ids # => "any string value can go here"
当列大小太小而无法容纳所有数据时,序列化数据可能会损坏。
你拼尽全力想要拔掉电源线,但为时已晚,控制你的胡言乱语、疯狂的意识将代码发布到 StackOverflow 上,让全世界都看到。最后,你陷入了混乱的睡眠。第二天,意识到自己的所作所为,你永远放弃编码,成为一名会计师。
道德
不要这样做