2014-09-19 64 views
0

请原谅我,如果这已经被问到(我相信它),但我找不到这个确切的问题(它是很可能我没有正确搜索)。Rails 4 - 通过集合选择相关模型(类似于.NET Linq的.SelectMany())

我有以下型号:

class Company < ActiveRecord::Base 
    has_many :jobs 
end 

class Job < ActiveRecord::Base 
    belongs_to :company 
    has_and_belongs_to_many :tags 
end 

class Tag < ActiveRecord::Base 
    has_and_belongs_to_many :jobs 
end 

我试图做到的是由公司的标签列表,但我无法弄清楚如何(我要指出,我对Ruby和Rails来说很新鲜)。我来自.NET的背景,Linq我会使用类似Company.Jobs.SelectMany(j => j.Tags)的东西。

我试着做Company.first.jobs.tags,其失败NoMethodError: undefined method 'tags' for #<Job::ActiveRecord_Associations_CollectionProxy:0x892dca0>,但奇怪的是,如果我一轨控制台上运行Company.first.jobs.instance_methods,有一个:标签的方法。这是我所得到的,当我使用控制台的自动完成:

rails console

有什么建议?

谢谢。

回答

2

你在找什么叫'有很多通过'。

class Company < ActiveRecord::Base 
    has_many :jobs 
    has_many :tags, through: :jobs 
end 

这是你如何去通过关联(在这种情况下jobs),以获得该协会的协会。

这样您就可以在公司的一个实例上运行company.tags

+0

我只想澄清一点 - 与您现有方法的问题是,乔布斯是一个集合,但你必须打在个别情况下的方法。这将无需调整:'Company.first.jobs.collect {| job | job.tags}'。 – 2014-09-19 22:06:54

+1

@BradWerth你可以发布你的建议作为答案吗?这正是我所期待的。谢谢。 – 2014-09-22 13:48:56

+0

@ptd谢谢!它像一个魅力! 现在我试图做相反的事情,但我有一个不一致:标签应该由公司确定(给定的标签应该与来自同一家公司的工作相关联)。现在,我唯一的选择是在Tag类中使用'has_many:through'。 有没有什么办法可以设置它,以便标签只能拥有(或属于)一个公司? – 2014-09-22 15:13:14

1

您现有的方法存在的问题是作业是一个集合,但您需要在单个实例上点击该方法。这将不调整工作:

Company.first.jobs.collect { |job| job.tags }