Путь псевдоним, это возможно? - PullRequest
5 голосов
/ 07 июня 2010

У меня есть модель автомобиля:

Маршруты:

map.resources :vehicles, :has_many => :suppliers

Все отлично работает, но у Vehicle есть логический атрибут is_truck . Я хочу сделать Псевдоним, чтобы я мог получать те же ресурсы, фильтруя только грузовики, я пробовал:

Маршруты:

map.trucks '/trucks', :controller => :vehicles, :action => :index, :is_truck => true
map.trucks '/trucks/by_supplier/:supplier', :controller => :vehicles, :action => :index, :is_truck => true

Первый работает хорошо, но когда я ищу в Форме, второй не работает и ищет всех поставщиков.

Контроллер:

class VehiclesController
   def index
     if params[:supplier]
       @vehicles = Vehicle.all :conditions => { :is_truck => params[:is_truck] }
     else
       @vehicles = Vehicle.all
     end
   end
   ...
end

Форма поиска:

<% form_for :truck, :url => {:controller => :trucks, :action => :index}, :html => {:method => :get} do |f| %>
  <% f.text_field :search %>
  <% f.submit 'Search Trucks' %>
<% end %>

Возможно ли map.resources в качестве псевдонима?

Ответы [ 5 ]

1 голос
/ 12 июня 2010

Просто измените ваши маршруты следующим образом:

map.resources :vehicles, :has_many => :suppliers,
                         :collection => { :trucks => :get }

И проверьте rake routes для маршрутов, которые это генерирует. Это позволит вам перечислить транспортные средства, которые являются грузовыми автомобилями:

trucks_vehicles GET /vehicles/trucks(.:format)
                    {:controller=>"vehicles", :action=>"trucks"}

Так что теперь вам просто нужно добавить новое действие под названием «грузовики», которое работает подобно «index». Формы должны отслеживать самостоятельно (через поля формы), если вы создаете грузовик или другое транспортное средство. Не пытайтесь обойтись с маршрутизацией рельсов, что, как правило, означает, что дизайн вашего приложения имеет недостатки, что впоследствии приведет к неприятностям.

Вы можете взглянуть на STI (наследование одной таблицы: одна таблица хранит несколько классов транспортных средств). Другой способ - создать контроллер грузовых автомобилей, который наследует от контроллеров транспортных средств и перезаписывает только некоторые методы, например:

class TrucksController < VehiclesController
  def new
    @is_truck = true
    super
  end
  ...
end

или

class TrucksController < VehiclesController
  before_filter :this_is_a_truck
  ...

  private

  def this_is_a_truck
    @is_truck = true
    super
  end
end

Обновление: Вот еще один (если у вас есть столбец is_truck):

class TrucksController < VehiclesController
  around_filter :with_truck_scope
  ...

  private

  # Scope every active record access with an is_truck condition
  # you may want to put this directly into the model to get rid of the .send
  # method and directly access "Vehicle.with_truck_scope &block" here
  def with_truck_scope(&block)
    Vehicle.send :with_scope, :find => { :conditions => "is_truck = 1" },
                              :create => { :is_truck => 1 }, &block
  end
end

Но я действительно рекомендую сначала попробовать параметры :collection и :member маршрутизации Rails.

1 голос
/ 12 июня 2010

Я нашел более чистый способ сделать это, но Поиск по-прежнему не работает под конкретным поставщиком:

# Show all vehicles
map.connect '/vehicles/supplier/:supplier', :controller => :vehicles, :action => :index
map.resources :vehicles

# Only show trucks
map.connect '/trucks/supplier/:supplier', :controller => :vehicles, :action => :index, :is_truck => true
map.resources :vehicles, :as => 'trucks', :requirements => { :is_truck => true }

Ресурс: http://api.rubyonrails.org/classes/ActionController/Resources.html

0 голосов
/ 12 июня 2010

Я рекомендую вам использовать другой ресурс, просто добавив:

map.resources :vehicles, :as => :trucks, :has_many => :suppliers

Затем обработайте его в вашем контроллере следующим образом:

def index 
  conds = {}
  conds = { ... } if request.uri =~ /trucks/ # you can be more specific about the regexp if you need to
  @vehicles = Vehicle.all :conditions => conds      
end

Что вы думаете об этом?

0 голосов
/ 07 июня 2010

Не уверен, что возможно создать псевдоним, но, по крайней мере, вы можете попробовать поменять маршруты:

map.trucks '/trucks/by_supplier/:supplier', :controller => :vehicles, :action => :index, :is_truck => true
map.trucks '/trucks', :controller => :vehicles, :action => :index, :is_truck => true

Поскольку маршруты работают как «сначала добавлено - имеет более высокий приоритет», ваше решение может потерпеть неудачу, так как map.trucks '/ truck' catch '/ trucks / by_supplier /: supplier' также Также я бы порекомендовал немного изменить его:

map.with_options :controller => :vehicles, :action => :index, :is_truck => true do |v|
  v.trucks '/trucks/by_supplier/:supplier'
  v.trucks '/trucks'
end
0 голосов
/ 07 июня 2010

Вы обрабатываете это в своем контроллере?

что-то вроде:

class VehiclesController
   def index
     if params[:supplier]
       @vehicles = Vehicle.all :conditions => { :supplier_id => params[:supplier] }
     else
       @vehicles = Vehicle.all
     end
   end
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...