另一種方式來做到這一點是可能要使用的slug_candidates
(雖然我不認爲它會提供你想要的確切功能):
#app/models/product.rb
class Product < ActiveRecord::Base
extend FriendlyID
friendly_id :slug_candidates, use: :slugged
def reference
SecureRandom.hex(3).upcase
end
private
def slug_candidates
[
[:name, :reference]
]
end
end
好的,我剛剛意識到這正是你已經做的。如果有人想看到對這個問題的另一種解釋,我仍會發布答案。如有必要,我會刪除。
別的東西,你可以希望要考慮的是在數據庫中實施uuid
:
通用唯一標識符(UUID)是軟件建設使用的標識符標準。一個UUID只是一個128位的值。每個位的含義由幾個變體中的任何一個定義。
大多數人都會撕開我,甚至暗示這一點;你有喜歡的字符串替換您id
主鍵:de305d54-75b4-431b-adb2-eb6b9e546014
我們與我們的一些東西,做到這一點:
有這幾個好處,包括您可以參考單個對象不管他們存儲在哪裏,並且 - 正如你所發現的那樣 - 使用uuid
的能力就像一個slu。子彈。
你可以隨心所欲,我想實現一個uuid
然後進行friendly_id
更新after_create
:
#app/models/product.rb
class Product < ActiveRecord::Base
extend FriendlyID
friendly_id :slug_candidates, use: :slugged
after_create :set_new_friendly_id
private
def slug_candidates
[
[:name, :uuid]
]
end
def set_new_friendly_id
self.save #-> I know a double SQL call, but only way to get UUID
end
def should_generate_new_friendly_id?
uuid.present? #-> only updates if uuid is present
end
end
爲了得到uuid
工作,你可以選擇使用MySQL中uuid()
功能,或者在PGSQL的uuid_generate_v4
功能:
# db/schama.rb
create_table "nodes", force: :cascade, id: false do |t|
t.string "uuid", limit: 255, default: (Rails.env.staging? ? "uuid_generate_v4();" : 0), null: false
t.string "type", limit: 255
t.string "slug", limit: 255
t.string "title", limit: 255
t.text "value", limit: 65535
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
execute "ALTER TABLE nodes ADD PRIMARY KEY (uuid);"
if Rails.env.staging? #-> Heroku PGSQL
execute("CREATE EXTENSION IF NOT EXISTS \"uuid-ossp\"")
else
execute("DROP TRIGGER IF EXISTS before_insert_nodes;") #http://stackoverflow.com/a/5945220/1143732
execute("CREATE TRIGGER before_insert_nodes BEFORE INSERT ON nodes FOR EACH ROW SET new.uuid = uuid();")
end
雖然這將UUID
世代帶出應用程序邏輯,但這意味着您只能在之後使用UUID 創建記錄。這就是爲什麼在friendly_id
中使用它可能是粗略的;但最終可能會爲您提供您想要的功能。
謝謝AbM,你說得對。現在它可以工作。 – htaidirt