使用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毫秒。
编写递归循环的正确方法是什么?欣赏是否给出了逐步说明。感谢。
答案 0 :(得分: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
答案 1 :(得分: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