Есть ли метод DRYer в этом контроллере? - PullRequest
1 голос
/ 14 апреля 2011

Использование 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, чтобы я не мог перекодировать макет представления.

Есть ли лучший способ написания контроллера?

Спасибо!

Ответы [ 2 ]

3 голосов
/ 14 апреля 2011

Правильный способ высушить это в Rails 2.3.X - это именованная область в вашей модели.Чрезмерные / повторные запросы в вашем контроллере - намек на запах кода.Если вы мне не верите, Джемис Бак получил мою спину!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 голос
/ 14 апреля 2011

Первый подход: используйте before_filter. upd: у вас это не сработает (я оставлю это здесь для образовательных целей)

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

http://railscasts.com/episodes/259-decent-exposure

По-моему, я предпочитаю использовать helper_method для такой работы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...