如何在Ruby on Rails控制器中手动连接具有不同属性名称的两个不同表

时间:2016-04-29 22:50:01

标签: sql ruby-on-rails ruby postgresql join

我目前正在创建一个在Ruby on Rails上运行的网站。在我尝试加入两个表格时,我遇到了一些问题, 费率 地点 ,我与之相关两个不同的属性名称。

费率: id rater_id rateable_id(此表中还有一些属性)

地点: id title body user_id(此表中还有一些属性)

以下是我尝试在SQL中执行的查询。

SELECT * 
FROM rates, locations
WHERE rates.rater_id = locations.user_id AND rates.rateable_id = locations.id

我已阅读rubyonrails.org提供的官方活动记录文件。我尝试过这些,但它不起作用。以下是我尝试在app\controllers\users_controller.rb

中植入的代码
@join_rating = Rate.joins(:locations).where("rates.rateable_id = locations.id AND rates.rater_id = locations.id")
@all_rating = @all_rating.where(rater_id: @user)
@count_all_rating = @all_rating.count

@join_rating,正在尝试使用不同的名称加入属性。

@all_rating,正在尝试使用用户ID过滤要显示的位置

@join_rating,正在尝试计算用户评分的位置总数

假设所有内容都设置正确且唯一的错误是我正在尝试执行的查询,我应该如何重写该语句,以便我能够使用@all_rating显示用户已评级的位置

谢谢!

2 个答案:

答案 0 :(得分:1)

几点:

在ActiveRecord中,您正在使用Rate类启动语句,这意味着结果将是Rate个对象的集合。因此,如果您要显示位置,则应该从Location类开始。

  

@locations_user_rated = Location.joins('INNER JOIN率ON   rates.rateable_id = locations.id')。where('rates.rater_id'=> @user)

如果你的ActiveRecord关联定义得很好,你可以这样做:

  

@locations_user_rated = Location.joins(:rates).where('rates.rater_id'=> @user)

“定义明确”仅表示您需要执行以下操作。请注意,我不确定我是否正确理解了您的模型关系。我在下面假设每个位置都有多种费率,而且Rate模型的字段名为rateable_id而不是location_id的原因是因为您希望:rateable为{ {3}}。这意味着您可能在rateable_type表中也有一个rates字段。

class Location < ActiveRecord::Base
  has_many :rates, as: :rateable
end

class Rate < ActiveRecord::Base
  belongs_to :rateable, polymorphic: true
end

如果不是这种多态,那么事情应该更简单,我强烈建议您遵循Rails的约定,只需在location_id模型上命名关系字段Rate而不是{{1 }}。然后你可以这样做:

rateable_id

如果您仍然不相信字段名称,您可以自定义内容并执行:

class Location < ActiveRecord::Base
  has_many :rates
end

class Rate < ActiveRecord::Base
  belongs_to :location
end

您可以找到有关如何自定义关联polymorphichere的更多信息。

答案 1 :(得分:0)

我强烈建议您利用ActiveRecord的has_manybelongs_tohas_many through:功能。

如果您为每个表设置模型,并使用正确的关系:

class User < ActiveRecord::Base
  has_many :ratings, foreign_key: :rater_id
  has_many :rated_locations, through: ratings, class_name: Location.name, source: :rater
end

class Rating < ActiveRecord::Base
  belongs_to :rater, class_name: User.name
  belongs_to :location
end

class Location < ActiveRecord::Base
  has_many :ratings
end

然后,要访问用户评分的位置,您只需致电

user.rated_locations