Rails için Yönlendirme kaynaklarında id parametresinin adını değiştirin


108

Dinamik parametreler yuvasını nasıl değiştireceğime baktım ve aynı şeyi yapan bu gönderiyi buldum. Post https://thoughtbot.com/blog/rails-patch-change-the-name-of-the-id-parameter-in

Temelde yaptığı şey, aşağıdaki yollar ise:

map.resources :clients, :key => :client_name do |client|
  client.resources :sites, :key => :name do |site|
    site.resources :articles, :key => :title
  end
end

Bu rotalar aşağıdaki yolları oluşturur:

/clients/:client_name
/clients/:client_name/sites/:name
/clients/:client_name/sites/:site_name/articles/:title

Çözümlerden biri def to_param, modeldeki yöntemi geçersiz kılmaktır, ancak bunu modelin kendisine dokunmadan istiyorum.

Ancak Rails 2.x için olduğundan, Rails 3 için aynısını nasıl başarabilirim?

Güncelleme

Bu uygulama Mongoid kullanıyor. AR değil. Yani, mücevher dostu afaik kullanılamaz.

Yanıtlar:


192

Raylar 4 ve 5

Rails 4'te, :paramtam olarak aradığınız şeyi yapıyor gibi görünen seçenek eklendi. Sen bir göz alabilir Rails 3 kod ile karşılaştırıldığında Raylar 4 kod .

Detaylar

Bunu routes.rbdosyanıza kolayca uygulayabilirsiniz :

# config/routes.rb

resources :posts, param: :slug

# app/controllers/posts_controller.rb

# ...
@post = Post.find_by(slug: params[:slug])
# ...

Rails 4'ün piyasaya sürülmesinden itibaren, bu işlevsellik Ray Kılavuzlarında belgelenmiştir .

Raylar 3

Maalesef, Rails 3'te :keyseçeneği resourceskaldırıldı, bu nedenle bu şekilde oluşturulan rotaların adını artık yalnızca fazladan bir seçeneği geçerek kolayca değiştiremezsiniz.

Detaylar

Geçtiğimiz yıl uygulamayı istediğiniz şekilde çalıştırdığınızı varsayıyorum, ancak Rails 3 in routes.rb. to_paramYöntemden biraz daha fazla çalışma gerektirecek . Hala rotalara özel parametreler kullanılarak tanımlanır tanımlayabilir scopeve match(veya 's kuzenleri get, put, post, ve delete). Eşleştiricide istediğiniz parametre adını yazmanız yeterlidir:

get 'clients/:client_name', :to => 'clients#show', :as => client

scope 'clients/:client_name' do
  get 'sites/:name', :to => 'sites#show', :as => site
end

Sizin resourcesiçin otomatik olarak oluşturulan tüm rotaları manuel olarak eklemeniz gerekir , ancak bu, aradığınız şeye ulaşır. Yinelemenin bir kısmını çıkarmak için :controllerseçeneği scopeve ek scopeblokları etkili bir şekilde kullanabilirsiniz .


DÜZENLEME (8 Mayıs 2014): Cevabın hem Rails 3 hem de 4 için bilgi içerdiğini daha açık hale getirin. Tam satır numaralarına gitmek için koda giden bağlantıları güncelleyin ve daha uzun süre çalışmaları için taahhütleri gerçekleştirin.

DÜZENLEME (16 Kasım 2014): Rails 4 şu anda en üstte olmalı ve oldukça uzun bir süredir Rails'in güncel sürümü olduğundan ilgili bilgileri içermelidir.

DÜZENLEME (9 Ağustos 2016): Çözümün hala Rails 5'te çalıştığını düşünün ve eski bağlantıları güncelleyin.


1
Temel olarak, Rails3 yeniden doldurulmak için yönlendiricide kaynaklar seçeneğini yarattı, ancak özel değişken adlarına sahip olmak adına geçersiz kılınması gerekiyor ... Hissediyor!
Augustin Riedinger

1
İşte paramraylar 3 seçeneğinin arka
portu

Bu, url yardımcılarını bozar. Bir nesneyi içeri aktarırsam veya bilgi bilgisini verirsem eksik [: slug] anahtarından şikayet edersem normal bir kimlik tabanlı rota oluşturmaya başlarlar. Nasıl düzeltileceğine dair bir fikriniz var mı?
RonLugge

9
Bilginize, iç içe geçmiş kaynakları kullanırsanız, ana kaynağın parametresi post_slugkafa karıştırıcı olabilir.
ghayes

4
Bu gerçekten iyi ama iç içe geçmiş kaynak için post_post_id gibi üst kimliğin parametre adını istemiyorsam ne yapabilirim?
Asnad Atta

45

Rails 4'te,: id parametrelerini değiştirmek için param seçeneğini geçin. Örneğin resources :photos, param: :photo_name/ fotoğraflar /: fotoğraf_adı oluşturacak


1

Sizi doğru anladıysam, istediğiniz şey client_nameURL'nizde yer alması id, değil mi?

Bunu, to_parammodelinizdeki yöntemi geçersiz kılarak yapabilirsiniz . Buradan daha fazla bilgi edinebilirsiniz .


1
Daha önce de belirttiğim gibi, modeli değiştirmeme kısıtlamam var. Yukarıda bahsedilen örnek Rails 3'te desteklenmiyor mu veya kullanımdan kaldırılıyor mu?
autodidact

1

Bunun için bir mücevher var, tıpkı her şey için bir mücevher olduğu gibi;)

FriendlyId'i raylarda bu tür davranışlar için kullanıyorum 3.

Modelinize aşağıdaki gibi bazı kodlar eklemenizi gerektirecektir:

class Client < ActiveRecord::Base
  has_friendly_id :name
end

... ve eğer müşterilerinizin URI ile uyumlu isimleri yoksa, bunun için bir sümüklü böcek kullanmak isteyebilirsiniz ki bunu da yapabilirsiniz has_friendly_id :name, :use_slug => true. Sümüklü böcek kullanırken, onları veritabanında da sürdürmeniz gerekecek.

Ve daha önce de belirtildiği gibi, buradato_param belgelendiği gibi hileyi hala raylar 3 ile kullanabilirsiniz . FriendlyId'i biraz daha çok yönlü buluyorum.


Dostu kimliği severim ve birçok projede kullandım. Aslında uygulamam Mongoid kullanıyor. Ve friendly_id bunu afaik desteklemiyor. Ve daha önce de belirttiğim gibi, kısıtlamam modeli değiştirmek değil.
autodidact

1
Firavun faresi kullanıyorsanız, bu işlevselliği elde etmek için mongoid sümüklü böcek var . Aslında kullanıyor to_param, ancak arka planda başka zekice şeyler de yapıyor. Bağlantıyı burada buldum: stackoverflow.com/questions/4744446/…
Frost

O mücevheri sevdim. Başka benzer bir slugoid var . Ama dediğim gibi, modeli değiştirmeme kısıtlamam var. Bu to_param, uygulamanın ön uç kısmını bozuyor. Aslında, yönlendirme yaklaşımı için umutsuzca bakıyorum, API'mi değiştirmem gerekiyor, ancak Model ve Ön Uç bölümünü uygulamadan bozmadan. Neden rotaları yalnızca belirttiğim gibi değiştirme yaklaşımına ve yukarıdaki rayların eski sürümleri için örnek gönderiye sahip olamıyorum ???
autodidact

Denetleyicilerinizi, özel rota anahtarlarınızı kullanması için yeniden yazmaya çalıştınız mı? Örneğin @client = Client.find(:name => param[:client_name]içinde ClientsController#show? İşe yarayabilir.
Frost

Client.where(:name => param[:client_name]).first, yani.
Frost

0

Rails 3'te, aşağıdaki gibi ad alanları ve kapsamların bir kombinasyonunu kullanarak kimlik anahtarlarını yeniden adlandırabilirsiniz (yine de çok hoş değil):

namespace :clients do
  scope "/:client_name" do
    namespace :sites do
      scope "/:name" do
         post "/:title" => "articles#create"
         ...
      end
    end
  end
end
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.