to_param in Ruby on Rails

Reading time ~1 minute

If I want a custom slug

I walk through this cutstom slug.

  1. create migration add_slug to add a column inside the Post
  2. generate_slug using before_save. Read all the ActiveRecord Callbacks
  3. If you want to find a specific Post, you can not use Post.find, you have to use Post.find_by slug: 'my-post'
  RAILS g migration add_slug

  # in migration
  def change
    add_column :users, :slug, :string
  end

  #/model/post
  after_validation 
  #OR before_save(every single time after savei it ), 
  #OR before_create(only call once)

  def generate_slug
    self.slug = self.title.gsub(' ', '-').downcase
    # self.slug = SecureRandom.base64(6)
  end

  #in rails c
  Post.all.each { |post| post.save }

  #overwrite the to_param method
  def to_param
    self.slug
  end

  #in controllers
  # post = Post.find(params[:id])
  #should be
  post = Post.find_by slug: params[:id]

If you look up the source code of Rails:

  @model ActiveREcord::Integration
  # File activerecord/lib/active_record/integration.rb, line 40
  def to_param
    # We can't use alias_method here, because method 'id' optimizes itself on the fly.
    id && id.to_s # Be sure to stringify the id for routes
  end

  user = User.find_by(name: 'Phusion')
  user_path(user)  # => "/users/1"

  # overide to_param
  class User < ActiveRecord::Base
    def to_param  # overridden
      name
    end
  end

  user = User.find_by(name: 'Phusion')
  user_path(user)  # => "/users/Phusion"

There are some resources I recommend to understand how the to_param work:

What is ORM in Rails mean?

Object Relational Mapping(ORM)This is confused topic. I had a friend ask me about the model in Rails, and I spent lots of time trying to ...… Continue reading

Why use thin controller with fat model?

Published on June 29, 2017