Добавление дополнительных параметров в ресурсы маршрута рельсов - PullRequest
6 голосов
/ 14 ноября 2009

То, что я хочу сделать, кажется простым, но может не быть «правильным»

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

В настоящее время у меня есть несколько именованных маршрутов, которые выглядят следующим образом.

map.gray_product_image "images/:product/:image/gray/:size.:format", :controller => 'images', :action => 'gray_product_image'

для меня хитрость в том, что если бы я создал это с использованием ресурсов Rails, я не знаю, как бы я указывал: size,: format или его «тип цвета».

Полагаю, я хотел бы добавить маршрут участника и указать свои параметры следующим образом.

map.resources :products do |products| 
  products.resources :images, :member => {:gray_product_image => {':image/:size.:format' => :get}}
end

В других случаях я хотел добавить дополнительную информацию к маршруту ресурса, но не знал как.

Любая помощь будет принята с благодарностью, Спасибо.

Ответы [ 3 ]

5 голосов
/ 14 ноября 2009

Нет хорошего способа удалить часть контроллера / id ресурса. Самое близкое, что вам предстоит сделать, - обмануть ActionController примерно так:

map.resources :gray, :path_prefix => "/images/:product/:image_id/", 
  :controller => 'images', :requirements => {:colour => "gray"}

, который будет производить маршруты типа www.site.com/images/product/4/gray/1234.html со следующим хешем params:

params => { 
  :image_id => 4,
  :id => 1234,
  :colour => "gray",
  :product => "product"
}

Формат не будет передан в явном виде, но он будет доступен в контроллере с помощью обычно средства response_to.

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

class ImagesController < ApplicationController
  def show
    @size = params[:id]
    @image = Image.find(params[:image_id])
    ...
  end
end

Это на самом деле лучше работает как фильтр так:

class ImagesController < ApplicationController
  def initialize_colour
    unless params[:colour].nil?
      @size = params[:id]
      @colour = params[:colour]
      @image = Image.find(params[:image_id])
    end
  end

  before_filter :initialize_colour, :except => [:index, :new, :create]

  ...

end

Однако, чтобы эффективно использовать эти маршруты, вам придется передать все эти дополнительные параметры в ваш URL для вызовов. Как это:

gray_url(size, :image_id => @image.id, :product => product)

Но помощники делают это легко.

module ApplicationHelper
  def easy_gray_url(image, size, product)
    gray_url(size, :image_id => image.id, :product => product)
  end
end
2 голосов
/ 14 ноября 2009

Ознакомьтесь с документацией для ресурсов . Вы найдете это:

Метод ресурсов принимает следующие параметры для настройки Итоговые маршруты: *: требования - установить требования к пользовательским параметрам маршрутизации; это хэш регулярных выражений (которые должны совпадать для соответствия маршрута) или дополнительных параметров. Например:

      map.resource :profile, :path_prefix => ':name', :requirements

=> {: name => / [a-zA-Z] + /,: extra => 'value'}

будет соответствовать только в том случае, если первая часть является буквенной, и передаст в контроллер параметр: extra. **

0 голосов
/ 14 ноября 2009

Я понял, что способ, которым я хочу представлять мои ресурсы, просто выходит за рамки обычных ресурсов Rails, и это нормально. Проблема, с которой я действительно столкнулся, заключалась в том, что каждый раз, когда я добавлял пыльник и называл маршрут, чтобы добраться до того, что я хотел, он чувствовал себя неправильно, я повторял себя и в своих маршрутах, и в своих действиях.

Я вернулся к простому созданию именованных маршрутов и провел немного времени в контроллере, чтобы мои маршруты были простыми. Вот то, что у меня сейчас есть, и я в порядке.

#routes.rb
map.with_options :controller => 'sketched_images', :action => 'show', :path_prefix => '/sketches', :name_prefix => 'sketched_', :color => 'grey' do |m|
  m.style "styles/:style/:color/:size.:format"
  m.design "designs/:design/:color/:size.:format"
  m.product "products/:product/:color/:size.:format"
  m.color_combo "colored_products/:color_combo/:size.:format"
end

class SketchedImagesController < ApplicationController
caches_page :show

before_filter :load_data
def show
  @size = params[:size] || 100
  respond_to do |wants|
    wants.png
    wants.jpg
  end
end

private

def load_data
  case 
  when params[:design]
    @image = ClothingDesign.from_param(params[:design]).sketched_image
    greyed
  when params[:style]
    @image = ClothingStyle.from_param(params[:style]).sketched_image
    greyed
  when params[:product]
    @image = Product.from_param(params[:product]).sketched_images.first
    greyed
  when params[:color_combo]
    @color_combo = ColorCombo.find_by_id(params[:color_combo])
    @object = @color_combo.colorable
    if @object.active? && !@object.sketched_images.blank?
      @image = @object.sketched_images.first
      colored
    else
      @image = @product.style.sketched_image
      dimmed
    end
  end
end

def greyed
  @blank = "#FFF"
  @print = "#000"
  @highlight = "#666"
end

def colored
  @blank = "##{@color_combo.blank_color.value}"
  @print = "##{@color_combo.design_color.value}"
  @highlight = "##{@color_combo.highlight_color.value}" unless @color_combo.highlight_color.blank?
end

def dimmed
  @blank = "#BBB"
  @print = "#000"
  @highlight = "#444"
end

end
...