-1

使用 Rails 3.2。我想了解如何编写正确的递归循环。这是关联和控制器:

# country.rb
class Country < ActiveRecord::Base
  has_many :states
end

# state.rb
class State < ActiveRecord::Base
  belongs_to :country
  has_many :zones
  has_many :cities, :through => :zones
end

# zone.rb
class Zone < ActiveRecord::Base
  belongs_to :state
  belongs_to :city
end

# city.rb
class City < ActiveRecord::Base
   has_many :photos, :as => :attachable
end

# photo.rb
class Photo < ActiveRecord::Base
  belongs_to :attachable, :polymorphic => true
  has_attached_file :data, :options
end

# countries_controller.rb
class CountriesController < ApplicationController
  def show
    @country = Country.find(params[:id], :includes => [:states => [:cities => :photos]])
    @photos = @country.country_photos
  end
end

我将在下面编写一个愚蠢的递归循环来解释我想要实现的目标:从城市获取照片:

# countries/show.html.erb
<%= @country.country_photos.inspect # just to test %>

# country.rb
class Country < ActiveRecord::Base
  def country_photos
    all_photos = []
    self.states.each do |state|
      state.cities.each do |city|
        city.photos.each do |photo|
          all_photos << photo
        end
      end
    end
  end
end
# Expected output: [photo_object_1, photo_object_2]

我试过mapcountry_photos

if (photos = state.map(&:cities).flatten.map(&:photos).flatten)
  photos
end

但它有性能问题:执行 400 毫秒。

编写递归循环的正确方法是什么?如果给出了逐步的解释,请欣赏。谢谢。

4

2 回答 2

2

使用 has_many :through,你已经用过了。

# country.rb
class Country < ActiveRecord::Base
  has_many :states
  has_many :cities, :through => :states
  has_many :photos, :through => :cities
end

# state.rb
class State < ActiveRecord::Base
  belongs_to :country
  has_many :zones
  has_many :cities, :through => :zones
end

# zone.rb
class Zone < ActiveRecord::Base
  belongs_to :state
  belongs_to :city
end

# city.rb
class City < ActiveRecord::Base
   has_many :photos, :as => :attachable
end

# photo.rb
class Photo < ActiveRecord::Base
  belongs_to :attachable, :polymorphic => true
  has_attached_file :data, :options
end

# countries_controller.rb
class CountriesController < ApplicationController
  def show
    @country = Country.find(params[:id])
    @photos = @country.photos
  end
end
于 2013-08-15T08:07:35.810 回答
0

不确定性能,但您可以尝试设置基准:

def country_photos
    Photo.where("city_id IN (select id from cities where cities.state_id IN (select states.id from states where country_id = ?))", self.id)
end

如果你的城市表包含 country_id 那么它可以写成:

def country_photos
   Photo.where("city_id IN (select id from cities where cities.country_id = ?)", self.id)
end
于 2013-08-15T08:06:11.863 回答