Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

Railsで、URLにIDでなく名前を入力して、アクセスする方法

More than 5 years have passed since last update.

showやeditなど、member系のアクションに、数値のIDなどではなく、TwitterIDのような一意の文字列でアクセスする方法。

例えば、

http://your.app.com/users/400

でなく

http://your.app.com/users/bob-smith

でアクセスできるようにする。

単純にURLのかっこ良さが上がる気がするし、文字列でのアクセスのみ受け入れるようにしたら、サイトの持っている情報のスクレイピング対策にもなる。

例として、適用するモデル名をUser、urlに使用するカラム名をcanonical_nameとする。ここではidcanonical_nameのどちらでもアクセスできるようにする例を書く。

モデル側のコード

app/models/user.rb
class User < ActiveRecord::Base
  validates :canonical_name,
    uniqueness: { case_sensitive: false },
    format: { with: /^[A-Za-z][\w-]*$/ },
    length: { minimum: 3, maximum: 25 }

  def to_param
    canonical_name ? canonical_name : id.to_s
  end

  def self.find_by_canonical_name_or_id(arg)
    find_by_canonical_name(arg) || find(arg)
  end
end

to_paramというActiveRecordのメソッドが肝。これで通常の表示がidからcanonical_nameに切り替わる。
validationは大体こんな感じにすると良いと思う。ここでは大文字小文字が違うだけのcanonical_nameは許さないようにしているが、そもそも大文字を禁止するのもありだと思う。
なお、ここではcanonical_nameが設定されていないUserもいることを前提としている。

コントローラー側のコード

app/controllers/users_controller.rb
class UsersController < ApplicationController
  before_filter :load_user, only: [:show, :edit, :update, :destroy]
  ## if you use cancan
  # load_and_authorize_resource :user, find_by: 'find_by_canonical_name_or_id'

  private
  def load_user
    @user = User.find_by_canonical_name_or_id(params[:id])
  end
end

数字でなくてもidの情報はparams[:id]に入って渡される。
canonical_nameでしかアクセスできないようにしたい時はload_userUser.find_by_canonical_nameを使えば良い。

別案

探すときに、find_by_canonical_name_or_idというのを使うとto_paramを変更しているクラスだけ、findでModelを探せなくなってしまう。これだと困る場合は、

app/models/user.rb
  def self.find(arg)
    find_by_canonical_name(arg) || super
  end

とfindを上書きしてしまえばいいかもしれない。

追記

https://gist.github.com/agnellvj/1209733 にもっといろんな方法が載っているのを発見。興味ある人は見てみるべし。

awakia
検索とか推薦とかやってきたエンジニア。早稲田の山名研出身。大学院の頃、論文を書こうとしない僕を見かねた教授に、北京のMSRAに追放されるが3ヶ月後無事帰還。 大学を卒業後、エンジニアのブラックホールとの別名を持つGoogleに吸収されそうになるが1年2ヶ月後無事生還。 現在は、Wantedly(https://www.wantedly.com/ )の4番目のエージェントとして救出活動に専念。
http://awakia-n.hatenablog.com/
wantedly
「シゴトでココロオドル」ためのビジネスSNS「Wantedly」の開発・運営をしています。
https://wantedlyinc.com/ja/presentations
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away