[英]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? 那么,我的假设完全错了吗?或者这是您的后继之路?
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.