使用ROR 2.3.8。
这是我的代码:
class CitiesController < ApplicationController
def show
...
end
def western
@city = City.find(params[:id])
@spots = Spot.paginate(
:conditions => ["(city=? or state=?) and country=? and shop_type=?", "#{@city.name}", "#{@city.name}", @city.country, "Places"],
:page => params[:page],
:per_page => 20,
:order => 'rating_average DESC'
)
end
def middle-east
@city = City.find(params[:id])
@spots = Spot.paginate(
:conditions => ["(city=? or state=?) and country=? and shop_type=?", "#{@city.name}", "#{@city.name}", @city.country, "Food"],
:page => params[:page],
:per_page => 20,
:order => 'rating_average DESC'
)
end
def asian
@city = City.find(params[:id])
@spots = Spot.paginate(
:conditions => ["(city=? or state=?) and country=? and shop_type=?", "#{@city.name}", "#{@city.name}", @city.country, "Accommodation"],
:page => params[:page],
:per_page => 20,
:order => 'rating_average DESC'
)
end
end
我创建了western.html.erb
,middle-east.html.erb
,asian.html.erb
和_shops.html.erb
。
所以前三个基本上都是空的,但产生_shops.html.erb
,以免我重新编码视图布局。
编写控制器有更好的方法吗?
谢谢!
答案 0 :(得分:3)
在Rails 2.3.X中干掉它的正确方法是模型中的命名范围。控制器中的过度/重复查询是一种代码味道的暗示。如果你不相信我,Jamis Buck已经退缩了! http://weblog.jamisbuck.org/2006/10/18/skinny-controller-fat-model
在您的Spot模型中:
# app/models/spot.rb
named_scope :by_type, lambda { |city, type|
{:conditions => ["(city=? or state=?) and country=? and shop_type=?", city.name, city.name, city.country, type] }
}
在您的城市控制器中:
#app/contollers/cities_controller.rb
before_filter :fetch_city, :except => :show
def western
@spots = paginate_spots("Places")
end
....
private
def fetch_city
@city = City.find(params[:id])
end
def paginate_spots(type)
Spot.by_type(@city,type).paginate(:page => params[:page],
:per_page => 20,
:order => 'rating_average DESC'
)
end
这样做的目的是从控制器中删除大部分查询逻辑。这是一件好事,因为它允许您按城市查找斑点,并在需要时键入其他控制器。分页可能特定于您的单个控制器,因此我倾向于将其从模型内的范围中排除。如果要构建API,则可能限制为50而不是20,例如,并希望按其他方法排序。
答案 1 :(得分:1)
第一种方法:使用before_filter
。 更新:它不适合你(我会把它留在这里用于教育目的)
class CitiesController < ApplicationController
before_filter :spots_and_city, :only => [:asian, :western, :middle-east]
def show
...
end
def western
end
def middle-east
end
def asian
end
private
def spots_and_city(type)
@city = City.find(params[:id])
@spots = Spot.paginate(
:conditions => ["(city=? or state=?) and country=? and shop_type=?", "#{@city.name}", "#{@city.name}", @city.country, "Accommodation"],
:page => params[:page],
:per_page => 20,
:order => 'rating_average DESC'
)
end
end
第二种方法使用helper method
:更新
class CitiesController < ApplicationController
helper_method :spots, :city
def show
...
end
def western
@city = city
@spots = spots("Places")
end
def middle-east
@city = city
@spots = spots("Food")
end
def asian
@city = city
@spots = spots("Accommodation")
end
private
def city
city ||= City.find(params[:id])
end
def spots(type)
spots ||= Spot.paginate(
:conditions => ["(city=? or state=?) and country=? and shop_type=?", "#{@city.name}", "#{@city.name}", @city.country, type],
:page => params[:page],
:per_page => 20,
:order => 'rating_average DESC'
)
end
end
第三:使用Decent Exposure
在我看来,我更喜欢使用helper_method
来完成这项工作。