开发者

Rails3 RSpec testing custom redirect route in routes.rb

I have a custom redirection in my routes.rb which works fine at the ui:

match ':hash' => redirect { |params| begin url = Shar开发者_如何学Going.find_by_short_url(params[:hash]); "/#{url.shareable_type}/#{url.shareable_id}/" rescue '/' end }, :constraints => { :hash => /[a-zA-Z0-9]{7}/ }

What is does is takes a shortened url and looks up the actual url path.

However my test is failing:

  it "routes GET 'STU1VWX' to stations/1" do
    { :get => "STU1VWX" }.should redirect_to(
      :controller => "stations",
      :action => "show",
      :params => {:id => 1}
    )
  end

With:

  1) Shorter URL redirect routes GET 'STU1VWX' to stations/1
     Failure/Error: { :get => "STU1VWX" }.should route_to(
     ActionController::RoutingError:
       No route matches "/STU1VWX"
     # ./spec/routing_spec.rb:12:in `block (2 levels) in <top (required)>'

So the problem is isolated at the test level. I know I could test this in a controller test but given that the code is in routes.rb I should not have to. Is there inherently a reason that using should route_to not to work in the case of redirection?


Looks like you're saying here that if you can't find the page belonging to the hash, then redirect to "/"

There's something really stinky about performing an ActiveRecord find in your routes.

If you have to redirect to a specific controller depending on the sharable type, then I'd put this as a separate controller with a redirect:

match "/:hash" => 'SharableController#redirect':constraints => { :hash => /[a-zA-Z0-9]{7}/ }

and then deal with finding the record and redirecting to the correct controller action from there:

class SharableController < ApplicationController

  def redirect
    @sharable = Sharable.find_by_sharable_type(params[:hash])
    redirect_to controller: @sharable.sharable_type, action: 'show', id: @sharable.id
  end

end

OR... depending on how similar the show actions are:

class SharableController < ApplicationController

  def redirect
    @sharable = Sharable.find_by_sharable_type(params[:hash])
    render template: "#{@sharable.sharable_type.pluralize}/show"
  end

end

If you're only dealing with GET requests, better to swap out match for get by the way:

get "/:hash" => 'SharableController#redirect', :constraints => { :hash => /[a-zA-Z0-9]{7}/ }
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜