#713 √ committed
Matt Darby

New Inflectors: Actionize and Parameterize

Reported by Matt Darby | July 27th, 2008 @ 03:39 PM | in 2.x

I've attached a patch that introduces two new Inflectors: Actionize and Parameterize. Each method is tested and documented.

Actionize

Transforms a string in titleize() form to a string suitable for a action name

  "Expense Report".actionize         # => "expense_report"
  "My Totally Cool Action".actionize # => "my_totally_cool_action"
   
  @reports = ['Expense Report', 'Employee Hours']
  @reports.each do |report_name|
    link_to(report_name, "/reports/#{report_name.actionize}")
  end
  # => "<a href = '/reports/expense_report'>Expense Report</a>
        <a href = '/reports/employee_hours'>Employee Hours</a>"

Parameterize

Replaces special characters in a string so that it may be used as part of a 'pretty' URL.

==== Examples

  class Person
    def to_param
      "#{self.id}-#{self.name.parameterize}"
    end
  end

  @person = Person.find(1)
  # => #<Person id: 1, name: "Donald E. Knuth">

  <%= link_to(@person.name, person_path %>
  # => <a href="/person/1-Donald_E_Knuth">Login</a>

Comments and changes to this ticket

  • Jim Cropcho

    Jim Cropcho July 27th, 2008 @ 06:03 PM

    #actionize seems useful, if only to have a more readable method for using existing functionality.

    i guess i could say the same about #parameterize, except that its function is to make a string url-safe, in a very generic way, and there are already methods (with appropriate naming, this time) which do that, right?

    http://api.rubyonrails.org/class...

    ActiveSupport::CoreExtensions::String::Inflections::underscore()

    is the same thing, I take it?

  • Matt Darby

    Matt Darby July 27th, 2008 @ 06:46 PM

    #underscore and #parameterize differ in how they handle spaces and special characters.

    >> "Donald E. Knuth".underscore
    => "donald e. knuth"
    >> "Donald E. Knuth".parameterize
    => "Donald_E_Knuth"
    

    It seems that #underscore expects a camelcased string, not a more human-readable one.

    #actionize is like #tableize, but it replaces spaces with underscores (by default), and doesn't pluralize the output.

    >> "Expense Report".tableize
    => "expense reports"
    >> "Expense Report".actionize
    => "expense_report"
    
  • Jim Cropcho
  • Jim Cropcho

    Jim Cropcho July 27th, 2008 @ 06:49 PM

    i guess it looks like the functionality doesn't exist, esp not under the proper naming per its usage. also, it seems genuinely useful.

  • Clemens Kofler

    Clemens Kofler July 28th, 2008 @ 06:46 AM

    • → Tag changed from “patch” to “activesupport inflector patch”

    actionize seems like a reasonable additional, although I haven't ever needed any funtionality similar to this.

    parameterize is a case by itself. There's lots of plugins out there that provide functionality to create URL friendly permalinks such as Rick's permalink_fu. If you have something like the parameterize functionality, you most definitely also have a permalink column in your model which defies the purpose of the method.

    Another thing to consider is that it doesn't play well with Rails' recent i18n efforts. In non-English speaking countries, it's likely that people's, places' etc. names include non-standard letters.

    Take Tarmo Tänav (sorry for using your name here ;-)) for example. With your Regexp, if we parameterized Tarmo, this would be something like 1-Tarmo_T_nav - which is almost certainly not what you'd want (and definitely not what Tarmo would want).

    To give you an idea what a German version of parameterize would look like, I've uploaded my current permalink creation method. Find it here. Oh, and by the way: When I wrote this code I was pretty new to Ruby and didn't know that Arrays are valid Hash keys - that's why it was inverted! ;-)

  • Claudio Poli

    Claudio Poli July 28th, 2008 @ 09:55 AM

    I usually use

    t = Iconv.new("ASCII//TRANSLIT", "utf-8").iconv(text)

    t = t.downcase.strip.gsub(/[^-_\s[:alnum:]]/, '').squeeze(' ').tr(' ', '-')

    (t.blank?) ? '-' : t

    for permalinks, can be optimized though.

  • Matt Darby

    Matt Darby July 28th, 2008 @ 12:53 PM

    @Clemens

    Actually, I don't use permalinks in this application. I simply override #to_param to make the link a little more helpful to the end user and for cheap SEO.

    You make a good point about #parameterize's anglo-centric-ness. I'm going to look at what kain posted and see if that will fill in the gaps.

    As for #actionize; it's really nice for DRYing up cases such as the 'report' example I listed earlier. At any rate it seems as though it would be a natural add to Inflector as the functionality doesn't exist.

  • Damian Janowski

    Damian Janowski August 4th, 2008 @ 09:28 PM

    Iconv behaves differently in different platforms. Ping Xavier Noria and he'll explain.

  • DHH

    DHH September 10th, 2008 @ 06:29 AM

    • → State changed from “new” to “committed”

    I like parameterize and have used that in quite a few cases. I don't think the anglo approach is that big of a deal, especially not since it's usually a good idea to keep those parts of the URL ascii anyway. I've changed a few defaults, though.

    I don't really see the general use of actionize, though. That seems pretty specific to your app.

  • Damian Janowski

    Damian Janowski September 10th, 2008 @ 01:24 PM

    @DHH: The point of using Iconv is not to have UTF8 URLs, but rather to "translate" special characters to their ASCII "equivalents" where possible.

    With the original patch:

    
    "Malmö".parameterize
    => "malm"
    

    With Iconv:

    
    "Malmö".parameterize
    => "malmo"
    

    I think this is very basic and should be provided out of the box. Or, at least, provide a L18N-aware extension point.

  • Karel Minařík

    Karel Minařík September 10th, 2008 @ 04:35 PM

    I second Damian. Discovered this only afterwrds in Github commits feed.

    I think the "dumb" transliteration like Malmö => "malm-" really is not a practice to be encouraged by Rails. (See dropping of letters on just about any Rails-based website, be it WWR, Slideshare, etc.)

    I have commented on the commit page

    In Czech context (accented latin characters) we mainly use this solution from Adam Ciganek :

    string.chars.normalize(:kd).to_s.gsub(/[^\x00-\x7F]/, '')
    

    Although the Iconv way is much more robust.

Please Login or create a free account to add a new comment.

You can update this ticket by sending an email to from your email client. (help)

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile »

Source available from github

The Git repository resides at http://github.com/rails

Check out the current development trunk (Edge Rails) with:

git clone git://github.com/rails/rails.git

Creating or reviewing a patch

See the contributor guide.

Creating a feature request

Please don't. If you want a new feature in Rails, you'll have to pull up your sleeves and get busy yourself. Or convince someone else to do it. See the contributor guide on how to get going. But posting them here is just going to lead to ticket root.

Creating a bug report

When creating a bug report, be sure to include as much relevant information as possible. Post the code sample that causes the problem. Preferably, alter the unit tests and show through either changed or added tests how the expected behavior is not occuring.

Security vulnerabilities should be reported via an email to security@rubyonrails.org, do not use trac for reporting security vulnerabilities. All content in trac is publicly available as soon as it is posted.

Then don't get your hopes up. Unless you have a "Code Red, Mission Critical, The World is Coming to an End" kinda bug, you're creating this ticket in the hope that others with the same problem will be able to collaborate with you on solving it. Do not expect that the ticket automatically will see any activity or that others will jump to fix it. Creating a ticket like this is mostly to help yourself start on the path of fixing the problem and for others to sign on to with a "I'm having this problem too".

Shared Ticket Bins