From 547999df256a5ac650eb012dabf713027b9bda1f Mon Sep 17 00:00:00 2001 From: Javan Makhmali Date: Thu, 14 Nov 2013 13:38:08 -0500 Subject: Add AR::Base.to_param for convenient "pretty" URLs derived from a model's attribute or method. --- activerecord/lib/active_record/integration.rb | 31 +++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'activerecord/lib') diff --git a/activerecord/lib/active_record/integration.rb b/activerecord/lib/active_record/integration.rb index f88c8e30e6..f881fa74b2 100644 --- a/activerecord/lib/active_record/integration.rb +++ b/activerecord/lib/active_record/integration.rb @@ -1,3 +1,5 @@ +require 'active_support/core_ext/string/filters' + module ActiveRecord module Integration extend ActiveSupport::Concern @@ -65,5 +67,34 @@ module ActiveRecord "#{self.class.model_name.cache_key}/#{id}" end end + + module ClassMethods + # Defines your model's +to_param+ method to generate "pretty" URLs + # using +method_name+, which can be any attribute or method that + # responds to +to_s+. + # + # class User < ActiveRecord::Base + # to_param :name + # end + # + # user = User.find_by(name: 'Fancy Pants') + # user.id # => 123 + # user_path(user) # => "/users/123-fancy-pants" + # + # Because the generated param begins with the record's +id+, it is + # suitable for passing to +find+. In a controller, for example: + # + # params[:id] # => "123-fancy-pants" + # User.find(params[:id]).id # => 123 + def to_param(method_name) + define_method :to_param do + if (default = super()) && (result = send(method_name).to_s).present? + "#{default}-#{result.truncate(20, separator: /\s/, omission: nil).parameterize}" + else + default + end + end + end + end end end -- cgit v1.2.3