【问题标题】:Rails: How do I model preferences? Should I use has_many :through?Rails:我如何建模偏好?我应该使用 has_many :through 吗?
【发布时间】:2011-05-23 13:08:47
【问题描述】:

我有两个模型:User 和 HairColor。用户只有一种头发颜色,但可以有多种头发颜色偏好。对此建模的最佳方法是什么?

这是我开始做的:

#models/user.rb
class User < ActiveRecord::Base
  belongs_to :hair_color
  has_many :preferences, 
  has_many :hair_colors, :through => :preferences
end

#models/hair_color.rb
class HairColor < ActiveRecord::Base 
  has_many :users
end

#models/preference.rb
class Preference < ActiveRecord::Base 
  belongs_to :user
  belongs_to :hair_color
end

使用 has_many : 通过正确的方法吗?另外,如果我想将其扩展到“眼睛颜色”等其他属性怎么办? (用户有一种眼睛颜色,但可以偏好多种眼睛颜色”

【问题讨论】:

    标签: ruby-on-rails model associations relationship


    【解决方案1】:

    发色数量有限,因此偏好表需要有一个hair_color_id 并按如下方式设置:

    #models/user.rb
    class User < ActiveRecord::Base
      has_one :hair_color
      has_many :preferences
    end
    
    #models/hair_color.rb
    class HairColor < ActiveRecord::Base 
      belongs_to :user
      belongs_to :preference
    end
    
    #models/preference.rb
    class Preference < ActiveRecord::Base 
      belongs_to :user
      has_many :hair_color
    end
    

    我相信这是正确的。如果您遇到任何障碍,请告诉我。


    当您添加眼睛颜色或任何其他特征时,您可能需要根据偏好做一些不同的事情。那时我会有 4 列:id, user_id, foreign_id, foreign_type

    foreign_id 将是 eye_color/hair_color 表中的 id,foreign_type 将是“eye”或“hair”之类的。然后在你的模型中,你会有这样的东西:

    #models/hair_color.rb
    class HairColor < ActiveRecord::Base 
      belongs_to :user
      has_many :preferences, :foreign_key => :foreign_id, :conditions => { "preferences.foreign_type" => "hair" }
    end
    

    这有点疯狂,但这是最干的方式。您可以在 eye_color.rb 中添加相同的内容,然后将 foreign_type 的“头发”替换为“眼睛”。

    【讨论】:

    • 谢谢!会试试这个。此外,要添加其他首选项(例如眼睛颜色),我是否只需要在首选项表中添加一个 eye_color_id 列?或者我应该将偏好分成不同的模型,例如“HairColorPreference”和“EyeColorPreference”?不确定哪个最干燥。
    • 更新了更多问题。
    • 查克,这太棒了。我正在撕扯头发,试图弄清楚并理解 has_many :through 关联。这似乎是最干燥的方法。所以现在,我将尝试一下,然后尝试让表单用于在视图模板中选择首选项。 Ruby on Rails 的新手,但希望它不会太难。谢谢!
    • 没问题的人!当你刚开始使用 Rails 时,你真的很困惑,但过了一段时间你就会开始欣赏它的约定和幕后发生的“魔力”。祝你好运!
    • 另外,为了将来参考,我见过的大多数人都使用 :through 来简单地改变他们的命名约定。因此,如果您想要 User.Choices,则必须输入 :has_many :choices, :through => :preferences。它还有其他用途,但不要高估它的实用性。
    猜你喜欢
    • 2011-08-11
    • 2012-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多