-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]

私はで使用mapしてみましたcountry_photos

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

ただし、パフォーマンスに問題があります。実行に 400 ミリ秒かかります。

再帰ループを書く適切な方法は何ですか? ステップバイステップの説明があれば感謝します。ありがとう。

4

2 に答える 2

2

has_many を使用してください。すでに使用しています。

# 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 に答える