Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/53.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails rails activerecord关系联接表_Ruby On Rails_Activerecord - Fatal编程技术网

Ruby on rails rails activerecord关系联接表

Ruby on rails rails activerecord关系联接表,ruby-on-rails,activerecord,Ruby On Rails,Activerecord,我有一个国家模型和一个旅行笔记模型。一个国家有许多游记,而一张游记属于一个国家 class TravelNote < ActiveRecord::Base default_scope { order(created_at: :desc) } belongs_to :country has_many :chapters before_destroy { draft? } validate :validates_uniqueness_of_draft, on:

我有一个国家模型和一个旅行笔记模型。一个国家有许多游记,而一张游记属于一个国家

class TravelNote < ActiveRecord::Base
  default_scope { order(created_at: :desc) }

  belongs_to  :country
  has_many    :chapters

  before_destroy { draft? }

  validate :validates_uniqueness_of_draft, on: :create

  enum status: { draft: 0, published: 1, archived: 2 }
  enum advice_against: { no: 0, general: 1, tourists: 2 }

  scope :country, ->(country_id) { where(country_id: country_id) }

  # further methods omitted...
end

class Country < ActiveRecord::Base
  default_scope { order(:iso_code) }

  has_many :travel_notes

end
出于性能原因,我想删除TravelNote.published.country(country.id).first.try:published\u at,这样就不再有数百个数据库查询,而只剩下一个等效sql查询的数组:

select * from countries 
left join travel_notes
on countries.id=travel_notes.country_id

如何实现它?

您可以编写一个自定义范围,只包含已发布的注释

差不多

scope :include_published, -> { proc do |_|
    joins("LEFT OUTER JOIN (
        SELECT b.*
        FROM   travel_notes b
        WHERE published = 1
        GROUP BY b.country_id
      ) notes_select ON notes_select.country_id = countries.id"
     ).select("countries.*").select("#{insert what attributes you want to include }")
  end.call(self, counted_model) }
您必须在第二个select子句中包含希望从注释中获得的属性,然后这些属性将作为同名方法包含在国家/地区活动记录结果中

SQL查询可以写得更漂亮,我只是拼凑了一些东西


我在我的项目中使用了类似的技术,但为了包括相关对象的计数。

显然,您正在尝试加载与国家相关的“旅行笔记”:

Country.includes(:travel_notes).where(travel_notes: { status: 1} )
因此,您的代码将是:


我不确定,但你能试试
TravelNote.published.joins(:country).where(:countries=>{:id=>country.id}).map(&:published_at)
如果它能帮助汉克斯·桑蒂亚,那确实是有帮助的。除非我遗漏了什么,否则你不需要
proc
在那里。关于proc可能是正确的,评论。我们有一个proc,因为我们将它提取到一个模块中,该模块根据所涉及的模型生成查询。非常感谢Albin Svensson。这很好,在另一种情况下,我肯定会使用您的方法,但在本例中,MohamedDia27的代码看起来更简单。
scope :include_published, -> { proc do |_|
    joins("LEFT OUTER JOIN (
        SELECT b.*
        FROM   travel_notes b
        WHERE published = 1
        GROUP BY b.country_id
      ) notes_select ON notes_select.country_id = countries.id"
     ).select("countries.*").select("#{insert what attributes you want to include }")
  end.call(self, counted_model) }
Country.includes(:travel_notes).where(travel_notes: { status: 1} )
class CountriesController < ApplicationController
  def index
    @countries = Country.includes(:travel_notes).where(travel_notes: { status: 1} )
  end
  # rest of the class omitted...
end
@countries.each do |country|
        %tr
          %td= link_to country.name_de, country_travel_notes_path(country)
          %td= country.travel_notes.first.published_at