1

这是关于处理模型字段的一般问题,只是想知道这是否是正确的方法。假设我有模型House,用户可以选择它具有的 10 个功能:

Swimming Pool
Hot Tub
Tennis Court
Boat Parking
Horse Facilities
Balcony
Pets Allowed
Energy Efficient
Lease Option
Disability Features

这意味着我必须制作 10 个布尔列,对吗?我从来没有使用过这么多的表格列,所以我不确定。有这么多是正常的做法吗?

谢谢你。

4

5 回答 5

6

另一种选择是有一个名为 HouseOptions 的表(或任何你喜欢的),然后是一个名为 UserHouseOptions 之类的连接表。

AR 关系如下所示:

# user.rb
has_many :user_house_options
has_many :house_options, :through => :user_house_options

# user_house_options.rb
belongs_to :user
belongs_to :house_options

# house_options.rb
has_many :user_house_options
has_many :users, :through => :user_house_options

然后,用户没有额外的列。它只是通过 AR 关系拥有那个连接表。用户住宅选项将有两列:user_id 和 house_options_is。然后 House Options 只有字符串列(“Swimming Pool”等),它只是一个参考表。

查看此 Rails 指南以获取有关 has_many :through 关系(和示例代码)的更多信息:http: //guides.rubyonrails.org/association_basics.html#the-has_many-through-association

于 2012-05-09T15:12:27.207 回答
4

我并不担心字段的数量,但您可能希望概括您的设计,以便您可以轻松实现新功能。

他是一个设计理念。

> rails generate Model Feature type:string house_id:integer

class House < ActiveRecord::Base
  has_many :features
end

class Feature < ActiveRecord::Base
  belongs_to :house
end

class SwimmingPool < Feature
  def to_s
    "Swimming Pool"
  end
end

house = House.create
house.features << SwimmingPool.new
house.save!

house.features.each do |feature|
  puts feature
end
于 2012-05-09T15:37:48.070 回答
2

这可能是可行的,但实现代码可能会很混乱。一种可能的解决方案是序列化

class User < ActiveRecord::Base
  serialize :preferences
end

user = User.create(:preferences => { "background" => "black", "display" => large })
User.find(user.id).preferences # => { "background" => "black", "display" => large }

在这里,我们使用的首选项只是一个哈希,但您也可以使用数组

另一种解决方案,为每个功能创建一个表并使用连接,但这可能会更麻烦哈。当我更多地思考这个问题时,我会更新我的答案

于 2012-05-09T15:13:00.387 回答
2

我的另一个答案(使用多态类)只是一个想法。另一种更简单的方法是有一个 feature_types 表,在名称字段中列出 Swimming Pool,以及一个多对多链接表。请参阅 has_many :through。

此表解决方案很容易扩展以添加另一种类型。

如果您想扩展特定于类的行为,多态类解决方案是可扩展的。例如,游泳池可能会根据特征表中的质量数据在 to_s 中包含诸如“奥林匹克规模”之类的数据。

于 2012-05-09T17:30:39.373 回答
1

这取决于您可以创建一个数组字段的用途,例如称为特征,您可以在该数组中插入房屋的特征类型。

于 2012-05-09T15:09:04.130 回答