Rails 3: пользовательские маршруты Restful: изменение поведения Edit-Action - PullRequest
1 голос
/ 24 февраля 2012

Для моего проекта мне нужны пользовательские URL, которые не должно быть легко угадать, как это происходит с увеличением числа объектов.Чтобы решить эту проблему, я дал своим объектам атрибут unique_id, который является строкой, и написал семь действий, которые будут сгенерированы самим resources :objects, который выглядит следующим образом:

  get '/objects' => 'objects#index', as: :objects 
  post '/objects' => 'objects#create'
  get '/objects/new' => 'objects#new', as: :new_object
  get '/:unique_id/edit' => 'objects#edit', as: :edit_object
  get '/:unique_id' => 'objects#show', as: :object
  put '/:unique_id' => 'objects#update'
  delete '/:unique_id' => 'objects#destroy'

Все это прекрасно работает, яЯ просто должен был сказать контроллеру, чтобы он нашел Объекты через Object.find_by_unique_id(params[:unique_id]) вместо Object.find(params[:id]). Я могу создать, прочитать и удалить идеально, но я не могу обновить.

Когда я открываю edit_object_path, он правильно отображает форму, но когда я нажимаю «Обновить объект», он облажается.Из вывода WEBrick я вижу, что он создает запрос PUT, но он запрашивает идентификатор объекта, а не unique_id.Так, например, вместо запроса PUT /osefushe7398hr9 он сообщает PUT /26.Метод update даже не вызывается, но вместо этого он просит создать новый объект с unique_id, равным 26.

Я действительно не знаю, где изменить это поведение или как передать уникальный_ид вместо идентификатора,

Ответы [ 3 ]

3 голосов
/ 24 февраля 2012

В моделях Rails есть метод, который вы можете переопределить для достижения этой цели, который называется методом to_param.Поведение этого метода по умолчанию - возвращать идентификатор экземпляра модели (что, я полагаю, вы пытаетесь изменить).

С вашим текущим макетом я бы сбросил все ваши изменения маршрута,В модели добавьте:

def to_param
  "#{unique_id.parameterize}"
end

Итак, теперь при обычной маршрутизации запрос / objects /: variable будет работать так, как вы хотите.

Используя метод параметризации, выбезопасно не наталкиваться на недружественные URL.

Небольшой недостаток переопределения метода to_param заключается в том, что теперь другие действия внутри контроллера, использующие метод Model.find (: edit,: update и: destroy) будутвсе должны быть изменены на Model.find_by_unique_id [если вы остаетесь RESTful].

1 голос
/ 24 февраля 2012

В форме вы можете явно указать, какой URL размещать и какие параметры использовать вместе с ним.Например (используя HAML и form_tag)

= form_tag object_path(@object.unique_id), :method => :put do

Вы также можете быть еще более явным с помощью:

= form_tag object_path(:id => @object.unique_id), :method => :put do
0 голосов
/ 29 февраля 2012

Хорошо, решение было добавить

def to_param
  unique_id
end

в объектную модель без параметризации или синтаксиса # {}.Я действительно обнаружил это случайно, пытаясь передать unique_id в форму, как упомянуто во втором решении.Оказывается, мне не нужно было менять тег form_for, как это было предложено во втором решении.Параметризация была причиной того, что unique_id был сделан в нижнем регистре.

Теперь все работает, как задумано (и все еще спокойно)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...