読者です 読者をやめる 読者になる 読者になる

Rails Webook

自社のECを開発している会社で働いています。Rails情報やサービスを成長させる方法を書いていきます

RailsでURLにモデルのID以外の値を表示するTips

Rails Tips

Railsでは、デフォルトでは次のように/products/1/users/1などモデルのIDが表示されます。
f:id:nipe880324:20141206161259p:plain:w480


これは、ActiveRecord(ActiveModel)のto_paramが使われているためです。
to_paramメソッドは、URLで使われるオブジェクトの文字列を返します。保存されていない場合は、nilを返します。

class Product < ActiveRecord::Base; end

product = Product.create
product.to_param # => "1"

product = Product.new
product.to_param # => nil

つまり、to_paramをオーバーライドすることで任意のURLを表示することが可能です。

# app/models/product.rb
class Product < ActiveRecord::Base
  def to_param
    "#{id}-#{name}"
  end
end


こうすることにより、次のようにURLに文字列が入った値を表示することができます。
f:id:nipe880324:20141206160447p:plain:w420


日本語もURLで表示することができます。
f:id:nipe880324:20141206160448p:plain:w420


もちろん、モデルの作成、更新、削除も問題なく動作します。これは、次のようになっているからです。

# params[:id] に "2-オレンジジュース" が入っている
params
#=> {:id=>"2-オレンジジュース"}

# to_i で数値化すると2のみになる
params[:id].to_i
=> 2

# そのため、コントローラの次のような箇所でも問題なく動作する
@product = Product.find(params[:id])

もし、URLにIDを入れたくない場合は、permalinkカラムを追加し、ユニークになる制限をDBとモデルに追加し、to_paramメソッドを次のようにすればよいでしょう。

# app/models/product.rb
def to_param
  permalink
end

もちろんコントローラ、ビューなどもpermalinkに合わせて対応させる必要があります。


以上です。