如何定义以下使用关系

时间:2010-09-15 10:50:06

标签: mysql ruby-on-rails

我需要有一个表,我可以在其中设置用户首选项,我希望有一个表,其中设置了所有首选项值,另一个关系表,其中我将拥有user_id和preference_id但我需要优先选择三个不同的页面

  1. item
  2. 最爱
  3. 最近。
  4. 我需要显示用户设置的结果列表,例如,如果在项目页面上用户想要显示20个结果,那么我想将prference id设置为1,其值为20。

    prefrence table 
    id
    value
    
    user_preferences 
    id
    item_result (foreign_key prefernce_id)
    favorite_result (foreign_key preference_id)
    recent_result (foreign_key preference_id)
    

    我想要的东西可以让我提取像user.item.name这样的值 同样的方式我想做user_preference.item_result.value

2 个答案:

答案 0 :(得分:0)

你以我认为不是最好的方式来定义你们的关系。您正尝试在用户和首选项之间创建多对多关系(用户有许多首选项,并且首选项由许多用户设置)。如果要将多余的字段(在这种情况下为值)添加到多对多关系中,可以将其添加到连接表(在本例中为用户首选项)。

我注意到您为首选项使用静态值,并且不希望为首选项本身创建模型(尽管如果您决定在将来扩展用户首选项,这将非常方便。) 试试这些模型:

class User < AR::Base
  has_many :user_preferences

  def item_preference
    user_preferences.find_by_preference_id(1).value
  end
end

class UserPreference < AR::Base
  # has 3 fields: user_id, preference_id and value
  belongs_to :user
end

这样,您可以通过执行user.item_preference或user.recent_preference找到首选项。如果你开始有很多偏好,这将不是最好的方法,但是你必须要面对的是。

最理想的情况是,您应该拥有一个名为“Preference”的第三个模型,而UserPreference模型将充当Preference和User模型之间的连接。

答案 1 :(得分:0)

我自己解决了这个问题。 在发布答案之前,我必须说每个人都应该使用rails console

我已将关系定义如下

class User < AR::Base
  has_one :item_preference
  has_one :item_preference, :through => :user_preference, :source => :item

  has_one :favorite_preference
  has_one :favorite_preference, :through => :user_preference, :source => :favorite

  has_one :recent_preference
  has_one :recent_preference, :through => :user_preference, :source => :recent

  has_one :user_preference
end

class UserPreference < ActiveRecord::Base
  belongs_to :item,
  :foreign_key => "item_results",
  :class_name => "Preference"

  belongs_to :favorite,
  :foreign_key => "favorite_results",
  :class_name => "Preference"

  belongs_to :recent,
  :foreign_key => "recent_results",
  :class_name => "Preference"

  belongs_to :user
end

class Preference < ActiveRecord::Base
  has_many :item_preferences,
    :foreign_key => "item_results",
    :class_name => "UserPreference"

  has_many :favorite_preferences,
    :foreign_key => "favorite_results",
    :class_name => "UserPreference"

  has_many :recent_preferences,
    :foreign_key => "recent_results",
    :class_name => "UserPreference"

end  

现在我可以访问值

User = User.find(16)
user.item_preference
[:] [DEBUG] [2010-09-16 17:09:54] [           App::OnlineOrdering] -   Preference Load (0.4ms)   SELECT `preferences`.* FROM `preferences` INNER JOIN `user_preferences` ON `preferences`.id = `user_preferences`.item_results WHERE ((`user_preferences`.user_id = 16)) 
=> #<Preference id: 1, value: "20", created_at: "2010-09-15 15:13:04", updated_at: "2010-09-15 15:13:04">

和其他方式

preference = Preference.find(1)

preference.item_preferences
[:] [DEBUG] [2010-09-16 17:09:23] [           App::OnlineOrdering] -   UserPreference Load (0.4ms)   SELECT * FROM `user_preferences` WHERE (`user_preferences`.item_results = 1) 
[:] [DEBUG] [2010-09-16 17:09:23] [           App::OnlineOrdering] -   UserPreference Columns (1.2ms)   SHOW FIELDS FROM `user_preferences`
=> [#<UserPreference id: 1, user_id: 16, item_results: 1, favorite_results: 2, recent_results: 2, created_at: "2010-09-15 15:13:04", updated_at: "2010-09-15 15:13:04">]