简体   繁体   English

我如何使用ActiveRecord通过中介模型对象有条件地获取一些模型的对象及其关联的模型的对象

[英]How can I get some model's objects and its associated model's objects conditionally through an intermediary model object, using ActiveRecord

How can I get some model's objects and its associated model's objects conditionally through an intermediary model object? 如何通过中介模型对象有条件地获取某个模型的对象及其关联的模型的对象? This will then be used to generate JSON (via to_json ). 然后,它将用于生成JSON(通过to_json )。

Here is the setup made more generic: 这是更通用的设置:

class JobSet < ActiveRecord::Base
  belongs_to :job_system
  has_many :resources, through => :job_system
  has_many :jobs
  ...
end

class JobSystem < ActiveRecord::Base
  has_many :job_sets
  has_many :resources
  ...
end

class Resource < ActiveRecord::Base
  belongs_to :job_system
  has_many_and_belongs_to_many :jobs
  ...
end

class Job < ActiveRecord::Base
  belongs_to :job_system
  belongs_to :job_set
  has_many_and_belongs_to_many :resources
  ...
end

What I want to do is get all of the resources with their corresponding jobs, but only the jobs that are part of a particular job set. 我想做的是获取所有资源及其相应的作业,但仅获取属于特定作业集的作业。

UPDATE : even if a resource doesn't have any jobs associated with it I still want to get it with the rest of the resources. 更新 :即使资源没有任何与之关联的工作,我仍然希望将其与其余资源一起使用。 The purpose is to display all resources with any jobs assigned to them. 目的是显示分配了所有作业的所有资源。

It looks like I can set conditions when using through , but I can't seem to figure out how to do that when it is the next objects associations I am after... 看来我可以在使用through时设置conditions ,但是当它是我所追求的下一个对象关联时,我似乎无法弄清楚该怎么做...

Is there a good name for this type of problem? 这种类型的问题有好名字吗? Is there any easy way to do this? 有没有简单的方法可以做到这一点?

UPDATE 2 : There seem to be solutions that work well within the controller, but I am using to_json in the view to preload for a canvas element. 更新2 :似乎有一些解决方案在控制器内运行良好,但我在视图中使用to_json预加载canvas元素。 It seems to automatically include all jobs when I do this: 当我这样做时,它似乎自动包含所有作业:

var resources = <%= @resources.to_json(:include => {:jobs => {:only => :id}}) %>; 

Would a manual SQL JOIN even help with this? 手动SQL JOIN甚至可以帮助您吗?

I think I know what you are after. 我想我知道你在追求什么。 The only thing I would ask you for is, if a resource does not have any jobs in this particular job set, should it still be included? 我唯一要问的是,如果资源在此特定作业集中没有任何作业,是否应该继续包含它?

Anyway, here is one way to do it: 无论如何,这是一种实现方法:

@resources = Resource.all(:include => :jobs,
                          :conditions => ["jobs.job_set_id = ?", @job_set.id])

This will NOT include the resources that has no jobs associated with @job_set 这将不包括没有与@job_set相关联的作业的资源

So, am I totally wrong in my assumptions, or was this what you where after? 那么,我的假设完全错了吗?或者这是您的后继之路?

Edit 编辑

Okay, this was more difficult then I thought. 好吧,这比我想的要困难。 There are several solutions but none I really like. 有几种解决方案,但我都不喜欢。 You could do like this: 您可以这样:

@resources = Resource.all

@resources.each do |resource|
  resource.jobs.all(:conditions => ["jobs.job_set_id = ?", @job_set_id])
end

But that will result in the 1+n number-of-queries-problem putting pressure on your db. 但这将导致1 + n个查询问题,给您的数据库带来压力。

You could also do like this: 您也可以这样:

@resources = Resource.all(:include => :jobs)

@resources.each do |resource|
  resource.jobs.select{ |job| job.job_set_id == @job_set_id }
end

But that will result in more memory consumption on the server side since all jobs are loaded eagerly and then looped through to see which matches the job_set_id. 但这将导致服务器端更多的内存消耗,因为所有作业都被急切加载,然后循环遍历以查看哪些作业与job_set_id相匹配。

The problem with finding a better solution in my opinion is that this is something that should be specified in the SQL JOIN condition but I don't think that ActiveRecord lets us modify that in combination with eager loading. 我认为找到更好的解决方案的问题是,这应该在SQL JOIN条件中指定,但是我不认为ActiveRecord可以让我们结合急切的加载进行修改。

You should be able to do this in a pretty straight-forward way, but you may need the set in a particular format or structure other than what's given here: 您应该能够以一种非常简单的方式来执行此操作,但是您可能需要一种特定的格式或结构的集合,而不是此处给出的:

@resources = @job_set.resources.include(:jobs)

As a note, I'd advise against using the Rails 1 style has_many_and_belongs_to_many declarations. 请注意,我建议不要使用Rails 1样式的has_many_and_belongs_to_many声明。 The join tables they use are not model based and are very hard to manipulate, especially if they have meta-data associated with them, compared to a more modern join model approach. 与更现代的联接模型方法相比,它们使用的联接表不是基于模型的,并且很难操作,特别是如果它们具有与之关联的元数据。 You simply make a model called JobResource or ResourceJob depending on how you want to prioritize things, and build in two belongs_to relationships to join them together. 您只需根据想要对事物进行优先级排序的方式来创建一个名为JobResource或ResourceJob的模型,然后建立两个belongs_to关系以将它们连接在一起。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何使用ActiveRecord在Rails中返回关联的模型对象 - How to return associated model objects in Rails with ActiveRecord 如何迭代 ActiveRecord 对象的关联对象 - How to iterate an ActiveRecord object's associated objects ActiveRecord在模型对象的哪个级别上不会加载关联的对象 - At what level in a model object does ActiveRecord not load associated objects 如何在模型中创建仅返回那些关联等级大于current_user等级的对象的范围? - How can I create a scope in a model that returns only those objects with an associated rank greater than the current_user's rank? 如何更新模型对象的关联对象? - How do I update a model object's associated object? 在 ActiveRecord 集合中包含关联模型的属性 - Include associated model's attributes in ActiveRecord collection ActiveScaffold或ActiveRecord如何在关联模型的列上搜索 - ActiveScaffold or ActiveRecord how to search on an associated model's column 合并ActiveRecord模型对象 - Merge ActiveRecord Model objects 在 ruby​​onrails 中,如何从 ActiveRecord::Relation 对象获取关联的模型类? - In rubyonrails, how to get the associated model class from and ActiveRecord::Relation object? 根据相关模型的数据验证和ActiveRecord模型? - Validating and ActiveRecord model based on an associated Model's data?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM