Проблема с созданием пользовательских маршрутов в Ruby on Rails 3.1

#ruby #routing #controller #ruby-on-rails-3.1

#рубин #маршруты #контроллер #ruby-on-rails-3.1

Вопрос:

Кажется, я не могу настроить пользовательский URL-адрес. Все маршруты RESTful работают нормально, но я не могу понять, как просто добавить /:unique_url к существующим маршрутам, которые я создаю в модели (простая 4-символьная случайная строка) и которые будут служить своего рода «постоянной ссылкой».

Routes.rb

 resources :treks
match ':unique_url' => 'treks#mobile'
  

Контроллер

 .
.
def mobile
  @trek = trek.find(params[:id])
end
  

Это потому, что я пытаюсь определить пользовательское действие для существующего ресурса? Могу ли я не создавать пользовательские методы на том же контроллере, что и с ресурсом?

Кстати, когда я меняю routes.rb на match 'treks/:id/:unique_url' => treks#mobile , это работает нормально, но я просто хочу, чтобы URL-адрес был просто /:unique_url

Обновление Похоже, find_by_[parameter] что это правильный путь …

Я играл на консоли и, похоже, не могу найти никаких методов для продвижения… Trek.last.fullname Например, я могу бежать, но не могу бежать @trek = Trek.last …а затем вызовите… @trek.lastname например. Есть какие-либо подсказки, почему? Я думаю, что это моя проблема.

Комментарии:

1. Ваш mobile метод использует params[:id] , но у вас нет :id в вашем маршруте. Вам нужно будет создать find_by_unique_url метод в вашей модели (если у вас его еще нет) и использовать его в вашем mobile методе.

2. спасибо, Марк, где мне создать этот метод?

3. Если у вас есть unique_url поле, значит, оно у вас уже есть. В консоли Rails вы можете указать, Trek.find_by_unique_url(url) где url находится соответствующий unique_url, и вы увидите результат.

4. когда я запускаю это в консоли, там написано undefined method … я думаю, что не могу заставить find_by_unique_url работать. должно ли это быть где-то в моей модели?

5. @MarkThomas можете ли вы проверить мое обновление … я думаю, это может быть причиной проблемы… Спасибо!

Ответ №1:

Итак, есть ли в Trek поле, в котором хранится его уникальный URL? Если это так, вы должны делать что-то вроде этого:

 @trek = Trek.find_by_url(params[:unique_url])
  

Комментарии:

1. у меня есть поле, :unique_url которое я создаю в функции обратного вызова before_save .

2. Итак, в этом случае это было бы trek.find_by_unique_url(params[:unique_url])

3. @pruett нет, find_by_XXX методы генерируются «на лету» с помощью вызова Ruby method_missing! Итак, вместо XXX вы можете использовать любой из атрибутов, которые вы определили в модели

4. хм … теперь это есть в моем контроллере… но, похоже, это не работает. я получаю undefined method 'fullname' for nil:NilClass (полное имя) — это еще одно свойство моей модели, которое я вызываю с помощью <%= @trek.fullname %> , на мой взгляд

5. Действительно, смотрите apidock.com/rails/ActiveRecord/Base в разделе «Средства поиска на основе динамических атрибутов». Вы также можете сделать Trek.where(:unique_url => params[:unique_url])[0] , делает то же самое

Ответ №2:

 trek.find_by_unique_url( params[:unique_url] ) # should do the trick
  

@pruett нет, find_by_XXX методы генерируются «на лету» с помощью вызова Ruby method_missing! Итак, вместо XXX вы можете использовать любой из атрибутов, которые вы определили в модели.

Вы даже можете перечислить несколько атрибутов, таких как:

 find_by_name_and_unique_url( the_name, the_unigue_url)
  

Проверьте эти страницы:

http://guides.rubyonrails.org/active_record_querying.html

http://m.onkey.org/active-record-query-interface


если вы получаете undefined method ... for nil:NilClass , это означает, что объект, для которого вы пытаетесь вызвать этот метод, не существует, например, равен nil .

Вероятно, вы просто пропустили поставить оператор if перед этой строкой, чтобы убедиться, что объект не равен нулю

Комментарии:

1. я не знаю, что это было … может быть, я все время допускал опечатку???? в любом случае … кажется, сейчас работает. я думаю, что мой атрибут unique_url постоянно менялся при каждом обновлении, поэтому я преследовал движущуюся цель, спасибо за вашу помощь.

Ответ №3:

Хм. Обычно я бы сделал что-то вроде этого:

 map.connect "/:unique_url", :controller => "treks", :action => "mobile"
  

Тогда в этом контроллере идентификатор не будет применим .. вам нужно будет изменить его на что-то вроде этого:

 def mobile
  @trek = trek.find_by_unique_url(params[:unique_url])
end
  

(это если unique_url — столбец для поиска)

Комментарии:

1. Хах .. да, большинство моих приложений все еще застряли в версии 2.3 .. я еще не запустил все новые материалы.