#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 .. я еще не запустил все новые материалы.