在rails路由资源中添加额外的参数

Tor*_*inz 6 resources routing ruby-on-rails

我想做的事情似乎很简单,但可能不是"适当的"

假设我有一个图像资源,我根据网址操纵图像.在网址中,我想指定它的大小,以及它是否为灰色,彩色或暗灰色或其他条件.

目前我有一些看起来像这样的命名路线.

map.gray_product_image "images/:product/:image/gray/:size.:format", :controller => 'images', :action => 'gray_product_image'
Run Code Online (Sandbox Code Playgroud)

对我来说,诀窍是,如果我创建这个使用Rails资源,我不知道如何指定:size,:format,或者它是"颜色类型".

我想我想添加一个成员路由并指定我的参数,如下所示.

map.resources :products do |products| 
  products.resources :images, :member => {:gray_product_image => {':image/:size.:format' => :get}}
end
Run Code Online (Sandbox Code Playgroud)

还有一些时候我想在资源路线上添加额外的信息,但不知道如何.

任何帮助将不胜感激,谢谢.

EmF*_*mFi 5

没有好方法可以删除资源的控制器/ id部分.你最接近通过欺骗ActionController得到这样的东西:

map.resources :gray, :path_prefix => "/images/:product/:image_id/", 
  :controller => 'images', :requirements => {:colour => "gray"}
Run Code Online (Sandbox Code Playgroud)

哪个会产生类似www.site.com/images/product/4/gray/1234.html下面的params散列的路线:

params => { 
  :image_id => 4,
  :id => 1234,
  :colour => "gray",
  :product => "product"
}
Run Code Online (Sandbox Code Playgroud)

格式不会被明确传递,但它将通过通常的respond_to方式在控制器中可用.

接下来,你将不得不在控制器中运用一些魔法来欺骗铁轨做你想做的事.

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

这实际上更适合作为过滤器:

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
Run Code Online (Sandbox Code Playgroud)

但是,为了充分利用这些路线,您必须将所有这些额外参数传递给您的网址以进行呼叫.像这样:

gray_url(size, :image_id => @image.id, :product => product)
Run Code Online (Sandbox Code Playgroud)

但帮助者很容易做到这一点.

module ApplicationHelper
  def easy_gray_url(image, size, product)
    gray_url(size, :image_id => image.id, :product => product)
  end
end
Run Code Online (Sandbox Code Playgroud)


Tor*_*inz 0

我意识到我想要表示我的资源的方式不属于正常的 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
Run Code Online (Sandbox Code Playgroud)