Ruby On Rails で作成した Web アプリがあります。今のところ、オブジェクトを表示したいときは、次のページにアクセスする必要があります: http://mywebapp.com/object/1234 with 1234 オブジェクトの ID。
そのオブジェクト ID をエンコードして、次の結果を得たいと思います: http://mywebapp.com/object/5k (これは単なる例です)。
どうすればそれができますか?
どうもありがとう、
マーティン
Ruby On Rails で作成した Web アプリがあります。今のところ、オブジェクトを表示したいときは、次のページにアクセスする必要があります: http://mywebapp.com/object/1234 with 1234 オブジェクトの ID。
そのオブジェクト ID をエンコードして、次の結果を得たいと思います: http://mywebapp.com/object/5k (これは単なる例です)。
どうすればそれができますか?
どうもありがとう、
マーティン
これらの変換方法はすべて可逆的であるため、オブジェクトに名前やタイトルなどがある場合は、スラグを追加するのが最善の方法です。このような場合、新しい属性 :slug をオブジェクトに追加し、モデルのオブジェクト名 (またはその他のもの) からその値を自動的に生成します。
class MyObject
validates_format_of :slug, :with => /\A[a-z\-0-9]*\Z/
before_validation :generate_slug, :on => :create
def generate_slug
if self.slug.blank?
slug = self.name.mb_chars.downcase.normalize(:kd).to_s.gsub(/-/, " ").squeeze(" ")
slug = slug.gsub(/\s/, "-").gsub(/[^a-z\-0-9]/, "")
current = 1
self.slug = slug
while true
conflicts = MyObject.where("slug = ?", self.slug).count
if conflicts != 0
self.slug = "#{slug}-#{current}"
current += 1
else
break
end
end
end
end
end
その場合、URL はhttp://mywebapp.com/object/my_object_slugになります。実際には、このスラッグを介してオブジェクトを見つけるためです。
class MyObjectController
def some_action
my_object = MyObject.find_by_slug(params[:slug])
...
end
end
routes.rb を変更することを忘れないでください:
match "object/:slug", :to => "my_objects#some_action"
おそらく Base64 エンコーディングでこれを行うことができます (ただし、内部 ID を秘密にしようとしている場合は、Base64 エンコーディングを使用していると誰かが推測し、ID を簡単に特定できる可能性があります)。
あなたのコントローラーはこのように見える必要があります
class ThingsController < ApplicationController
require 'base64'
def show
@thing = Thing.find Base64.urlsafe_decode64(params[:id])
end
def edit
@thing = Thing.find Base64.urlsafe_decode64(params[:id])
end
#These are just a couple of very simple example actions
end
実際に URL をエンコードするのは少しトリッキーになるでしょう - 興味深い問題のように見えるので調べてみます (ただし、約束はしていません)。
少し読むと、ActionView が url_for の to_param メソッドを使用してオブジェクトの ID を取得していることがわかります。モデル自体でこれをオーバーライドして、IDを次のようにエンコードできます
class Thing < ActiveRecord::Base
def to_param
Base64.urlsafe_encode64 self.id.to_s
end
end
ここに書いたことはすべて推測です。以前にこれを実行したり、コードをテストしたりしたことがないため、機能するかどうか、または予期しない問題が発生するかどうかについては保証できません. どうやって行くのか、とても興味があります。