Skip to content

Instantly share code, notes, and snippets.

@matenia
Created February 25, 2012 14:35
Show Gist options
  • Save matenia/1908782 to your computer and use it in GitHub Desktop.
Save matenia/1908782 to your computer and use it in GitHub Desktop.
Route Constraints, mapping Friendly Id 4.x to /:id of any model
# app/models/page.rb
class Page < ActiveRecord::Base
extend FriendlyId
friendly_id :title, :use => [:slugged, :history]
end
# config/initializers/page_constraint.rb
class PageConstraint
# uses friendly_id 4.x
def initialize
@page_paths = Page.includes(:slugs).collect(&:slugs).flatten.map { |a| "/#{a.slug}" }
end
def matches?(request)
@page_paths.include?(request.path)
end
end
# app/observers/page_observer.rb
class PageObserver < ActiveRecord::Observer
def after_save(record)
# record is the Page#object that was just saved
Rails.application.reload_routes!
end
end
### NOTE:
# REMEMBER TO ADD THIS TO config/application.rb
# Include the following
# you will see some information that has already been commented out ..
# Tell the app to look in the app/observers directory for files
# config.autoload_paths += %W(#{Rails.root}/app/observers)
# Tell the app that we have an observer now ..
# config.active_record.observers = :page_observer
# config/routes.rb
AwesomeApp::Application.routes.draw do
resources :pages
root :to => 'welcome#index'
# placed at bottom so as not to mangle other paths
get '/:id' => 'pages#show', :as => 'public_page', :constraints => PageConstraint.new
end
@SergeyKishenin
Copy link

What if you have some route that have the same name as a page's slug? It will render show action for the page but not that route.

I tried to add && request.params[:controller] == 'pages' to matches? but it didn't help. Any ideas?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment