如何 UNION 表并使结果在 Ruby 视图中可访问
How to UNION tables and make results accessible in a Ruby view
我对 RoR 和为我正在学习的课程创建学生项目还很陌生。我想构建一种我们在课程中没有涉及的查询类型,我知道我可以在 .NET 和 SQL 中快速完成。虽然以 Ruby 方式实现它,但我有一段时间了。
我想做的事情: 在用户的页面上显示该用户的所有 "posts" 朋友的列表。
"Posts" 在 questions
table 和用户贡献的 blurbs
table 中都可以找到。我想 UNION
这两个到一个记录集中按 updated_at DESC.
排序
然而,table 列名称并不相同,这是我的症结所在,因为我看到的其他成功答案取决于两者之间的列名称是否相同。
在 SQL 中我会写类似的东西(强调 like):
SELECT b.Blurb AS 'UserPost', b.updated_at, u.username as 'Author'
FROM Blurbs b
INNER JOIN Users u ON b.User_ID = u.ID
WHERE u.ID IN
(SELECT f.friend_id FROM Friendships f WHERE f.User_ID = [current user])
ORDER BY b.updated_at DESC
UNION
SELECT q.Question, q.updated_at, u.username
FROM Questions q
INNER JOIN Users u ON q.User_ID = u.ID
WHERE u.ID IN
(SELECT f.friend_id FROM Friendships f WHERE f.User_ID = [current user])
ORDER BY b.updated_at DESC
用户模型的(适用)关系是:
has_many :friendships
has_many :friends, through: :friendships
has_many :questions
has_many :blurbs
而且问题和模糊模型都有 belongs_to :user
在视图中,我想显示 'UserPost' 列和 'Author' 的内容。我确信这是可能的,我对 ActiveRecord 以及语句的形成方式还太陌生。很高兴收到一些意见或查看专门针对此问题的任何相关链接!
最终解决方案
希望这会在将来帮助其他人解决 Ruby UNION
问题。感谢@Plamena 的输入,最终实现为:
def friend_posts
sql = "...the UNION statement seen above..."
ActiveRecord::Base.connection.select_all(ActiveRecord::Base.send("sanitize_sql_array",[sql, self.id, self.id] ) )
end
你最好的方法就是使用 Rails
的力量
如果你想要一个用户朋友的所有东西:
current_user.friends.find(id_of_friend).first.questions
这会得到某个朋友的所有问题。
现在,您似乎在多个地方都有文字(如果您不提供文字如何与其他地方联系的模型,则很难想象)。你能提供这个吗?
@blurbs = Blurb.includes(:user)
@blurbs.each do |blurb|
p blurb.blurb, blurb.user.username
end
目前 Active Record 缺少联合支持。您可以使用 SQL:
sql = <<-SQL
# your sql query goes here
SELECT b.created_at ...
UNION(
SELECT q.created_at
....
)
SQL
posts = ActiveRecord::Base.connection.select_all(sql)
然后你可以迭代结果:
posts.each do |post|
# post is a hash
p post['created_at']
end
我对 RoR 和为我正在学习的课程创建学生项目还很陌生。我想构建一种我们在课程中没有涉及的查询类型,我知道我可以在 .NET 和 SQL 中快速完成。虽然以 Ruby 方式实现它,但我有一段时间了。
我想做的事情: 在用户的页面上显示该用户的所有 "posts" 朋友的列表。
"Posts" 在 questions
table 和用户贡献的 blurbs
table 中都可以找到。我想 UNION
这两个到一个记录集中按 updated_at DESC.
然而,table 列名称并不相同,这是我的症结所在,因为我看到的其他成功答案取决于两者之间的列名称是否相同。
在 SQL 中我会写类似的东西(强调 like):
SELECT b.Blurb AS 'UserPost', b.updated_at, u.username as 'Author'
FROM Blurbs b
INNER JOIN Users u ON b.User_ID = u.ID
WHERE u.ID IN
(SELECT f.friend_id FROM Friendships f WHERE f.User_ID = [current user])
ORDER BY b.updated_at DESC
UNION
SELECT q.Question, q.updated_at, u.username
FROM Questions q
INNER JOIN Users u ON q.User_ID = u.ID
WHERE u.ID IN
(SELECT f.friend_id FROM Friendships f WHERE f.User_ID = [current user])
ORDER BY b.updated_at DESC
用户模型的(适用)关系是:
has_many :friendships
has_many :friends, through: :friendships
has_many :questions
has_many :blurbs
而且问题和模糊模型都有 belongs_to :user
在视图中,我想显示 'UserPost' 列和 'Author' 的内容。我确信这是可能的,我对 ActiveRecord 以及语句的形成方式还太陌生。很高兴收到一些意见或查看专门针对此问题的任何相关链接!
最终解决方案
希望这会在将来帮助其他人解决 Ruby UNION
问题。感谢@Plamena 的输入,最终实现为:
def friend_posts
sql = "...the UNION statement seen above..."
ActiveRecord::Base.connection.select_all(ActiveRecord::Base.send("sanitize_sql_array",[sql, self.id, self.id] ) )
end
你最好的方法就是使用 Rails
的力量如果你想要一个用户朋友的所有东西:
current_user.friends.find(id_of_friend).first.questions
这会得到某个朋友的所有问题。
现在,您似乎在多个地方都有文字(如果您不提供文字如何与其他地方联系的模型,则很难想象)。你能提供这个吗?
@blurbs = Blurb.includes(:user)
@blurbs.each do |blurb|
p blurb.blurb, blurb.user.username
end
目前 Active Record 缺少联合支持。您可以使用 SQL:
sql = <<-SQL
# your sql query goes here
SELECT b.created_at ...
UNION(
SELECT q.created_at
....
)
SQL
posts = ActiveRecord::Base.connection.select_all(sql)
然后你可以迭代结果:
posts.each do |post|
# post is a hash
p post['created_at']
end