Rails Routing with Query String - PullRequest
       19

Rails Routing with Query String

7 голосов
/ 13 февраля 2010

У меня проблема, когда мне нужны значения, переданные из запроса GET, и я не знаю, как настроить определение маршрутизации.

Объект My Category имеет тип (строка), цвет (строка) и множество продуктов. Я хочу создать простой веб-сервис, который позволит вызывающей стороне получать все продукты категории, передавая тип и цвет категории:

http://www.myapp.com/getProducts?catType=toy&color=red

или?

http://www.myapp.com/categories/getProducts?catType=toy&color=red

Как определить правильную маршрутизацию для этой ситуации? Существуют ли лучшие способы сделать это Restful-способом ... потому что я знаю, что Rails-Restful, так что если есть способ сделать это "правильно", то это было бы еще лучше.

Спасибо

Ответы [ 2 ]

11 голосов
/ 13 февраля 2010

Ваш первый пример:

map.getproduct '/getProduct', :controller => 'your_controller', :action => 'your_action'

В контроллере у вас будет catType и цвет в хэше params:

params[:catType]
=> 'toy'
params[:color]
=> 'red'

Есть ли лучший способ? Наверное, да, но это зависит от ваших потребностей. Если у вас всегда будут параметры catType и color, вы можете добавить маршрут следующим образом:

map.getproduct '/getProduct/:catType/:color', :controller => 'your_controller', :action => 'your_action'

Вы получите доступ к этим параметрам с помощью хэша params, как в предыдущем примере. И ваши URL будут выглядеть так:

www.myapp.com/getProduct/toy/red

Если ваши параметры могут измениться, вы можете использовать маршрутизацию:

    map.getproduct '/getProduct/*query', :controller => 'your_controller', :action => 'your_action'

Тогда он будет перехватывать все запросы, которые имеют www.my.app.com/getProduct/... в начале. Но у вас будет больше работы в контроллере. У вас будет доступ к query с этим:

 params[:query]

и для www.myapp.com/getProduct/color/red/catType/toy это даст:

 params[:query]
 => ['color', 'red', 'catType', 'toy]

Так что вы должны разобрать его вручную.

4 голосов
/ 13 февраля 2010

Один RESTful способ сделать это - задействовать ресурс продукта, вложенный в ресурс категории, например:

http://www.myapp.com/categories/toy/products?color=red

Ваш route.rb должен содержать:

  map.resources :categories do |category|
    category.resources :products
  end

Так как мой URL выше с использованием атрибута типа Category для маршрутизации, я подразумеваю, что каждый тип уникален, как идентификатор. Это будет означать, что всякий раз, когда вы загружаете категорию в контроллере категорий (или где-либо еще), вам необходимо загружать категорию с Category.find_by_type(params[:id]) вместо Category.find(params[:id]). Мне нравятся категории маршрутизации таким образом, когда это возможно.

Ваше действие индекса контроллера ProductsController будет искать товары, используя строки вроде:

  @category = Category.find_by_type(params[:category_id])
  @products = @category.products.find(:all, :conditions => { :color => params[:color]} ) 

Помните, ваша модель категории должна содержать строку:

has_many :products

Вероятно, неплохо бы применить это в модели с проверками:

validates_presence_of :type
validates_uniqueness_of :type

Чтобы маршрутизация работала, вам также следует переписать метод to_param в модели категории, чтобы он возвращал тип вместо id:

def to_param
  self.type
end
...