Ruby on Rails 3多个关联

时间:2015-06-10 18:48:58

标签: ruby-on-rails ruby-on-rails-3 associations polymorphic-associations

我有以下协会:

class User < ActiveRecord::Base
  has_many :shopping_requests
  has_many :recommendations, :through => :shopping_requests
end


class ShoppingRequest < ActiveRecord::Base
  belongs_to :user
  has_many :recommendations
end


class Recommendation < ActiveRecord::Base
  belongs_to :shopping_request
  has_one :user, :through => :shopping_requests
end

现在我需要添加一个Compliment类。用户可以赞美另一个用户(所以我有一个user_from_id和一个user_to_id)。购物请求和/或推荐可以给予赞美;并且没有限制(对于任何数量的购物请求以及推荐,用户可以由同一用户或其他用户给予多次称赞)。

我知道要使Compliment具有多态性但不确定与用户/购物请求/推荐相关的最佳方式是什么。

我希望能够运行这样的查询:

  • user_to_id.compliments(获取用户的所有赞美);
  • user_to_id.shopping_request.compliments(获取所有用户对特定购物请求的赞美;
  • user_to_id.recommendation.compliments(获取所有用户对特定推荐的赞美;对于此特定查询,运行user_to_id.shopping_request.recommendation.compliments也很好);
  • user_from_id.compliments(获取用户给予另一个的所有赞美);
  • user_from_id.shopping_request.compliments(获取此用户为特定shopping_request提供的所有赞美)等....

那么为Compliment类设置关联的最佳方法是什么?

1 个答案:

答案 0 :(得分:1)

这是我的第一次挥杆。你已编写的代码可以使用,我没有在这里复制它。

class User < ActiveRecord::Base
  ...
  has_many :outgoing_compliments, class_name: "Compliment", foreign_key: "from_id"
  has_many :incoming_request_compliments, through: :shopping_requests, source: compliments
  has_many :incoming_recommendation_compliments, through: :recommendations, source: compliments
  ...
end


class ShoppingRequest < ActiveRecord::Base
  ...
  has_many compliments, as: :compliment able
  ...
end


class Recommendation < ActiveRecord::Base
  ...
  has_many compliments, as: :complimentable
  ...
end

class Compliment < ActiveRecord::Base
  belongs_to :complimentable, polymorphic: true
  #relies on two DB columns, complimentable_id and complimentable_type

  belongs_to :complimenter, class_name: "User", foreign_key: "from_id"
end

我对您的数据库进行了一次更改,因为您已经定义了它。 Compliment知道它属于哪个Complimentable,并且由于每个Complimentable都知道其用户,因此保存补充用户是多余的。您可以选择添加行...

class Compliment
  belongs_to :complimented, class_name: "User", foreign_key: "from_id"

class User
  has_many :incoming_compliments, class_name: "Compliment", foreign_key: "to_id"

......但我认为不会。

这些是您需要创建的关联。但是,您所需的一些方法调用不够具体。一个例子:

  

user_to_id.shopping_request.compliments(获取所有用户的所有内容)   对特定购物请求的赞美;

因为您编写的是User的实例方法,我们可以假设用户已知。但是,由于用户可以拥有许多 ShoppingRequests,因此通过您编写的内容,无法通过一个特定的请求来展示“赞美”。