从集合中选择外部值

问题描述:

我得到了3个与会者,测试用户和任务,与会者通过多对多关系连接测试用户&任务。现在我的问题是:为什么可以通过“test.ids”检索所有的id,而不是通过“test.testuser_ids”检索testuser_ids(如下面的rails console输出)?从集合中选择外部值

schema.rb

ActiveRecord::Schema.define(version: 20141027151350) do 

    create_table "attendees", force: true do |t| 
    t.integer "task_id" 
    t.integer "testuser_id" 
    t.boolean "participate" 
    t.datetime "created_at" 
    t.datetime "updated_at" 
    end 

    create_table "tasks", force: true do |t| 
    t.string "title" 
    t.text  "text" 
    t.datetime "created_at" 
    t.datetime "updated_at" 
    t.datetime "task_date" 
    t.boolean "participate" 
    end 

    create_table "testusers", force: true do |t| 
    t.string "username" 
    t.datetime "created_at" 
    t.datetime "updated_at" 
    end  
end 

轨控制台:

irb(main):030:0> test = Attendee.all 
    Attendee Load (0.2ms) SELECT "attendees".* FROM "attendees" 
=> #<ActiveRecord::Relation [#<Attendee id: 1, task_id: 1, testuser_id: 1, participate: true, created_at: "2014-10-29 16:29:43", updated_at: "2014-10-29 16:29:43">, #<Attendee id: 2, task_id: 1, testuser_id: 2, participate: true, created_at: "2014-10-29 16:29:43", updated_at: "2014-10-29 16:29:43">, #<Attendee id: 3, task_id: 1, testuser_id: 3, participate: nil, created_at: "2014-10-29 16:29:43", updated_at: "2014-10-29 16:29:43">, #<Attendee id: 4, task_id: 1, testuser_id: 4, participate: nil, created_at: "2014-10-29 16:29:43", updated_at: "2014-10-29 16:29:43">]> 
irb(main):031:0> test.ids 
    (0.2ms) SELECT "attendees"."id" FROM "attendees" 
=> [1, 2, 3, 4] 
irb(main):032:0> test.testuser_ids 
NoMethodError: undefined method `testuser_ids' for #<Attendee::ActiveRecord_Relation:0x00000106011ab0> 

是不可能的,因为默认情况下,Rails不会按照您的要求提供它。 即使我不知道我得到了你想要做什么,但我认为这些人是你的解决方案:

Attendee.all.first.testusers.ids 

这将让来自特定与会者所有testusers IDS。 相反,如果您从所有与会者希望所有testusers ID,您将需要一个循环:

res = [] 
Attendee.all.each { |a| res += a.testusers.ids } 
res.uniq 
+1

对你的答案只是一个简短的评论。除了'Attendee.all.each {}',你可以简单地使用'Attendee.pluck(:testuser_id)'。加载与会者的所有字段,然后遍历所有记录在这里是一个很大的开销。 – blelump 2014-10-29 17:06:17

+0

不错的建议:)我没有写出答案的表现,但是,你的评论肯定是有道理的。 – iMacTia 2014-10-29 17:13:18

+0

非常感谢!工作得很好 - 即使我不明白为什么我无法以正常方式访问测试数组: – 2014-10-30 10:27:15

看起来你失踪协会为您Attendee模型。它应该有:

class Attendee 

    belongs_to :testuser 

end 

除此之外,你不能叫Attendee.first.testuser_ids因为attendees表是有testuser_id。否则,改变你的模型模式。

+0

你能解释这样对我?我的参加者类已经有belongs_to:testuser&belongs_to:任务集!我没有得到的是,当我输入“test = Attendee.all”时,我收到了一系列与会者,但为什么可以获取ID,但无法获取testuser_ids? - 我对数据库不太熟悉 - 所以有可能我只是没有找到正确的东西... – 2014-10-30 10:25:48

+1

好吧,让我们从头开始。 'test = Attendee.all'只给所有参加者。现在,如果你要输入'test.class',你会看到'Attendee :: ActiveRecord_Relation'(我假设你至少使用了Rails 4.0--这里很重要)。如果你只想得到testuser_id,你可以输入'Attendee.pluck(:testuser_id)'(这是一种优先选择)。如果你不喜欢它,也可以键入'Attendee.all.collect(&:testuser_id)'(性能更差,因为你正在获取完整的记录,而只需要'testuser_id')。 – blelump 2014-10-30 13:50:32

+1

最后,回答你的问题,为什么你不能输入'Attendee.all.testuser_ids'。你不能,因为'Attendee.all'返回一个集合(它的类型是'Attendee :: ActiveRecord_Relation'),而不是一个单独的对象。如果你有一个关联'has_many testusers',那将是可能的。但是,这里没有意义。你应该学习什么是一个集合,你可以用它做什么以及什么是一个单一的对象。这个页面:我希望,http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html真的很有帮助,并且可以让你理解它。 – blelump 2014-10-30 13:56:47