我对Rails中的某些事情感到困惑(使用Rails 5)。我有这个模型
class MyEventActivity < ApplicationRecord
belongs_to :event_activity
end
我要做的是获取链接到它的所有对象的列表,换句话说,所有&#34; event_activity&#34;对象。我认为这会做到这一点
my_event_activities = MyEventActivity.all.pluck(:event_activity)
但它给了我这个SQL错误
(2.3ms) SELECT "event_activity" FROM "my_event_activities"
ActiveRecord::StatementInvalid: PG::UndefinedColumn: ERROR: column "event_activity" does not exist
LINE 1: SELECT "event_activity" FROM "my_event_activities"
如何获取链接到MyEventActivity对象的对象?请注意,我不想要ID,我想要整个对象。
编辑:这是所要求的PostGres表
eactivit=# \d event_activities;
Table "public.event_activities"
Column | Type | Modifiers
--------------------------+-----------------------------+----------------------------------------------------------------
id | integer | not null default nextval('event_activities_id_seq'::regclass)
name | character varying |
abbrev | character varying |
attendance | bigint |
created_at | timestamp without time zone | not null
updated_at | timestamp without time zone | not null
答案 0 :(得分:2)
EventActivity.joins(:my_event_activities).distinct
返回已关联EventActivity
条记录
MyEventActivity
个对象
或者你已经尝试过的更多内容:
EventActivity.where(id: MyEventActivity.all.pluck(:event_activity_id).uniq)
但第一个因其简洁和性能而更受欢迎。
假设我们有100 event_activities
,除了最后一个(id: 100
)之外的所有my_event_activities
都有100 my_event_activities
,总共9900 EventActivity.where(id: MyEventActivity.all.pluck(:event_activity_id).uniq)
。
SELECT "my_event_activities"."event_activity_id" FROM "my_event_activities"
执行两个SQL查询:
event_activity_id
将返回9900个非唯一Array#uniq
的数组。我们希望将此减少为唯一ID以优化第二个查询,因此我们调用SELECT "event_activities".* FROM "event_activities" WHERE "event_activities"."id" IN (1, 2, 3, ... 97, 98, 99)
,它在大型阵列上有自己的性能成本,将9900减少到99.然后我们可以调用第二个查询:{{1} }
EventActivity.joins(:my_event_activities).distinct
只执行一个SQL查询:SELECT DISTINCT "event_activities".* FROM "event_activities" INNER JOIN "my_event_activities" ON "my_event_activities"."event_activity_id" = "event_activities"."id"
。一旦我们进入数据库,我们就不必切换回Ruby来执行一些昂贵的过程,然后再次返回数据库。 joins
旨在在这种情况下执行这些类型的可链接和可组合查询。
可以使用简单的基准检查性能差异。实际的Postgres数据库加载了100个event_activities
,其中99个有100个my_event_activities
:
require 'benchmark/ips'
require_relative 'config/environment'
Benchmark.ips do |bm|
bm.report('joins.distinct') do
EventActivity.joins(:my_event_activities).distinct
end
bm.report('pluck.uniq') do
EventActivity.where(id: MyEventActivity.all.pluck(:event_activity_id).uniq)
end
bm.compare!
end
结果:
Warming up --------------------------------------
joins.distinct 5.922k i/100ms
pluck.uniq 7.000 i/100ms
Calculating -------------------------------------
joins.distinct 71.504k (± 3.5%) i/s - 361.242k in 5.058311s
pluck.uniq 73.459 (±13.6%) i/s - 364.000 in 5.061892s
Comparison:
joins.distinct: 71503.9 i/s
pluck.uniq: 73.5 i/s - 973.38x slower
<9>慢973倍:-O! joins
方法意味着用于这样的事情,这是Ruby中的一个令人愉快的案例,其中更具可读性也更高效。