代码之家  ›  专栏  ›  技术社区  ›  Joshua Pinter

RubyonRails:选择嵌套模型的所有记录的简单方法?

  •  0
  • Joshua Pinter  · 技术社区  · 14 年前

    只是好奇,我花了一段令人尴尬的时间试图获得一个嵌套模型中所有记录的数组。我只是想确定没有更好的方法。

    设置如下:

    我有三个相互嵌套的模型(Facility>>Tags>>Inspections),为Routes生成这样的代码。rb:

    map.resources :facilities do |facilities|
      facilities.resources :tags, :has_many => :inspections 
    end
    

    我想对一个设施进行所有的检查,我的代码是:

    def facility_inspections
      @facility = Facility.find(params[:facility_id])
      @inspections = []
      @facility.tags.each do |tag| 
        tag.inspections.each do |inspection|
          @inspections << inspection
        end
      end
    end
    

    这是可行的,但这是最好的方法吗?我认为这很麻烦。

    2 回复  |  直到 8 年前
        1
  •  3
  •   klew    14 年前

    你可以使用 has_many :through 协会。在您的模型中:

    # Facility model
    has_many :tags
    has_many :inspections, :through => :tags
    
    # Tag model
    belongs_to :facility
    has_many :inspections
    

    你可以做这样的检查:

    @inspections = Facility.find(params[:facility_id]).inspections
    

    但是,如果您在facility和tag之间有habtm关系,那么它将更加复杂,您必须手动编写一些SQL,如下所示:

    @inspections = Inspection.all(:joins => "INNER JOIN tags ON tags.id = inspections.tag_id INNER JOIN facilities_tags ON tags.id = facilities_tags.tag_id", :conditions => ["facilities_tags.facility_id = ?", params[:facility_id] )
    

    当然,上面的代码取决于您的表结构。如果你展示它,那么就更容易给出正确的答案:)。希望它有帮助!

        2
  •  0
  •   PreciousBodilyFluids    14 年前
    @facility = Facility.find(params[:facility_id], :include => {:tags => :inspections})
    

    这将对数据库执行一个查询(原始解决方案将使用其中的许多查询),并返回包含所有标记和检查的Facility对象。然后你可以做如下的事情:

    @inspections = @facility.tags.map(&:inspections).flatten