1

我需要一些帮助来构建一个表,然后在 Rails 3 中从该表中获取数据。

这是分解:

模型 - 这里涉及 3 个模型,它们是:

  • 线程有很多参与者
  • 参与者属于线程
  • 用户

活动表:

id | thread_id | participants

示例记录如下所示:

1 | 300 | 3,1,5,67,13
2 | 333 | 3,12
3 | 433 | 1,12
4 | 553 | 1,12, 67

其中参与者,是一个 user_ids 列表,如果有更好的方法来存储 user_ids,请告诉我。我还没有建造这个。

在我填充活动表之后。然后,我希望能够按照以下方式进行查询:选择参与者字段中包含 67 的参与者 ID 的所有活动记录。

我希望上面说的很清楚,如果没有,请告诉我。想法?想法?建议。

谢谢

4

1 回答 1

5

While it's tempting to store multiple values in a column, it always ends up with someone getting hurt. You're better off building a join table to relate the models.

For example you could do this:

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

That gives you three tables:

table: discussion_threads
columns: id

table: participations
columns: id | discussion_thread_id | user_id

table: users
columns: id

To find the threads in which a user is participating, just do:

@user.discussion_threads

And to find the users participating in a thread:

@discussion_thread.participants

Note: Thread is a reserved word in Ruby, so I've renamed it DiscussionThread

EDIT

mind showing an example of how to serialize an array of ids and then query against them?

You awaken in the middle of the night, and under the power of a strange compulsion you go to your computer and create this migration:

rails g model Abomination horror_ids:text

and model:

class Abomination < ActiveRecord::Base
  serialize :horror_ids
end

You test it to make sure it can store an array:

@abomination = Abomination.create(:horror_ids=>[2,33,42])
@abomination.horror_ids # => [2,33,42]

So what? You know that behind the scenes Rails converts it to YAML, which looks like this:

---\n
- 2\n
- 33\n
- 42\n

Again compelled by that wierd urging, you wonder "How could I search for a particular id stored in this column?". Well, it's just a string, right? You know how to find that in a text field:

cthulhu = 33
Abomination.where(["horror_ids LIKE '%- ?\n%'",cthulhu]).first

With increasing dread, you realize someone might stumble across this and think it was actually a good idea. It must be destroyed! But you are unable to type rm -rf *, instead the strange force makes you consider the quirks that a future mindless follower of Cthulhu developer might need to know, such as

@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"

And the fact that serialized data can get corrupted when the column size is too small to accommodate it all.

You make one last ditch effort to kick out the power cord, but it is too late, the gibbering, insane consciousness that has taken control of you posts the code on StackOverflow for the whole world to see. Finally you collapse into a troubled sleep. The next day, realizing what you've perpetrated, you give up coding forever and become an accountant.

Moral

Don't do this

于 2011-02-10T06:17:54.800 回答