March 18, 2015

Keresőbarát URL-ek Rails-ben

Van egy nagyon tuti gem, ami hozzásegít ahhoz, hogy az URL-ben számok helyett szöveg jelenjen meg. Például: www.example.com/posts/2 helyett www.example.com/posts/super-post. Ez azért is jó, mert a keresők jobban szeretik az ilyet - így akár előrébb is kerülhet az oldal a találati listákban. Másrészt, ha könyvjelzőkhöz adja egy felhasználó, vagy bemásolja valahová (például e-mailbe) a címet, akkor sokkal beszédesebb az URL-ben a bejegyzés címe, mintha csak egy ID-t tartalmazna.

A gem neve friendly_id. A dokumentációja itt található, a github oldala pedig itt.

A parancssorba/terminálba beírva telepíthetjük a legfrissebb verziót. Rails 4-hez legalább 5.0.0 kell. Nekem ma 5.1.0-t telepített. Pipa.

gem install friendly_id

Telepítés után adjuk hozzá az aktuális projektünk Gemfile-jához a friendly_id-t:

gem 'friendly_id'

Majd futtassunk parancssorban egy bundle-t, hogy települjön szépen:

bundle install

Következő lépésként a már meglévő táblánkhoz - amelyikből jelenleg ID-t mutatunk URL-ben - adjunk hozzá egy új oszlopot. Ezt - ahogy korábban bővebben leírtam - az alábbi módon tehetjük meg:

rails generate migration add_slug_to_posts slug:string

Hajtsuk végre a migrációt, parancssorba írjuk:

rake db:migrate

Ezután a model-ben kell megadnunk, hogy melyik oszlop tartalma jelenjen meg ID helyett az URL-ben. Jelenlegi példában a bejegyzés címét (title) adjuk meg (app/models/post.rb):

  extend FriendlyId
  friendly_id :title, use: :slugged

Így már az újonnan létrehozott bejegyzéseknek az URL-jében a cím jelenik meg. Ahhoz, hogy ezt meg is tudjuk nyitni, szükséges némiképp módosítani is az app/controllers/posts_controller.rb-t. A private method-ok között módosítanunk kell, hogy ne közvetlenül használja a title-t ID-ként, mert úgy sosem találja meg.

  # ezt egészítsük ki:
  @post = Post.find(params[:id])
  
  # erre:
  @post = Post.friendly.find(params[:id])

Figyelni érdemes arra is, hogy akár több bejegyzés is lehet azonos címmel. Ennek kezelése érdekében kapcsoljuk be a history-t a slug-okra. Ehhez annyi kell, hogy generálunk egy új migrációt és futtatjuk:

rails generate friendly_id
rake db:migrate

Bónusz: amennyiben vannak már korábbi bejegyzéseink, melyeknek az URL-je még nem szép, akkor rails console-ban átalakíthatjuk őket. Lépjünk be tehát a konzolba:

rails console

És frissítsük a bejegyzéseket:

  irb(main):001:0> Post.find_each(&:save)

Nandor Biro

Software Engineer working at Whereby, lover of all things countryside, life-long learner with a passion for IT and woodworking. Find him on Twitter.