1
# config/routes.rb
scope module: 'site' do
  root 'main#index'
  resources :post_categories, :path => "/", :only => [:index, :show] do
    resources :posts, :path => "/", :only => [:index, :show]
  end  
end

# app/models/post_category.rb
class PostCategory < ActiveRecord::Base
  has_many :posts

  def to_param
    seo_url
  end
end

# app/controllers/post_categories_controller.rb
  def show
    Category.find_by_seo_url(params[:id])
  end

seo_url - это поле при добавлении категории, типа "food"

Теперь статья открывается как

site.com/food/22

Но проблема в том что теперь она открывается и по адресу к примеру

site.com/sadsadas/22

Где sadsadas может быть любым набором символов.

В чем моя проблема я не пойму?

UDP D-Side

Я чуть изменил роутинг вот так

  resources :post_categories, path: '', only: :show do
    resources :posts, path: '/:year/:month/:day', only: :show, constraints: { year: /\d{4}/, month: /\d{2}/, day: /\d{2}/ }
  end

Хочу получить url такого вида /category/2015/11/08/id

где 2015.11.08 дата самого поста.

Как правильно из created_at обработать это все в котроллере post?

Так мало информации в интернете, а та что есть на английском.

Буду очень благодарен.

bismoney
  • 188
  • Возможный дубликат вопроса: Роуты и категории rails –  Nov 06 '15 at 19:52
  • Нет, это не дубликат, так как там вопрос как это реализовать. А тут я уже это реализовал, но появилась проблема и эту проблему я описал отдельно что бы было более понятно. – bismoney Nov 06 '15 at 19:59
  • Как же Русский стаковерфлов мало развит еще ( эхх. Не думал что роутинг станет для меня такой огромной проблемой. – bismoney Nov 06 '15 at 20:00
  • А... понял. У вас тут уже не роутинг, у вас обработка роута в контроллере. А реализация find_by_seo_url где? –  Nov 06 '15 at 20:04
  • Тут видно я туплю, скорее всего не зная как ее сделать. Сейчас погуглю – bismoney Nov 06 '15 at 20:17
  • Ну, раз её нет, то её ж надо сделать. В этом, видимо, и состоит вопрос. А загвоздка сейчас у вас в том, что вы игнорируете params[:post_category_id]. –  Nov 06 '15 at 20:19
  • Да простите, просто с руби у меня только начало взаимоотношений. Не могли бы скинуть какой-то пример или ссылку на подобное. Никак не могу нагуглить эту логику. Но в любом случае спасибо за наводку, попробую разобраться. – bismoney Nov 06 '15 at 20:22

1 Answers1

3

По-хорошему, у вас в вопросе не хватает кода контроллера. Но даже если его приложить, ответ толком не изменится.

Получив запрос по маршруту ко вложенному ресурсу, в контроллере нужный объект есть смысл искать такой же цепочкой вложенности:

@post = PostCategory.find_by!(slug: params[:post_category_id]) # достаём категорию
              .posts.find(params[:id]) # из её ассоциации posts достаём пост

Обращаю внимание, что используются "опасные" методы поиска ActiveRecord (find, find_by!), которые в случае отсутствия результата бросают исключение ActiveRecord::RecordNotFound. Избавляться от него нет необходимости: в средах production и аналогичных это исключение приводит к стандартной странице 404 Not Found, не светя текстом ошибки наружу.

  • Для сравнения, использование "тихого" find_by вернёт nil, если запись не найдётся. Попытка вызвать методы модели у nil'а приведёт к NoMethodError и ответу 500 Internal Server Error, что сигнализирует о неисправности в приложении.
  • PostCategory.find_by! на самом деле алиас к PostCategory.all.find_by!. Эти find<...>'ы есть у любого ActiveRecord::Relation, чем сам PostCategory не является.
  • Я просто не знаю как вас благодарить. 4 дня я не мог совладать с этим, просто не понимая логику как это работает. Побольше бы таких людей как Вы. Все получилось, поняв логику прописал в post_contriller @posts = PostCategory.find_by!(seo_url: params[:post_category_id]).posts.find(params[:id]) действительно по логам при запросе поста теперь происходит поиск нужной категории и seo_url а несуществующие категории выпадают в ActiveRecord::RecordNotFound. – bismoney Nov 06 '15 at 21:00
  • Если позволите задам еще два вопроса. Вы и так сильно помогли, поэтому можете не отвечать. Я начав делать полноценный сайт, не много бросился в омут с головой не освоив все. Обязательно это исправлю. – bismoney Nov 06 '15 at 21:03
  • Так вот, вопрос в том как теперь правильно обратиться к хелперу для получения ссылки на пост? post_category_post GET /:post_category_id/:id(.:format) site/posts#show. – bismoney Nov 06 '15 at 21:04
  • post_category_post_path(категория, пост) –  Nov 06 '15 at 21:05
  • И второй вы писали что использование в роутинге path => '' это довольно опасно. Если не трудно подскажите может ли это быть потом подводным камнем? И как правильнее все таки это реализовать? Или это в принципе не так страшно если правильно расставить блоки в роутингах? – bismoney Nov 06 '15 at 21:06
  • Это нормально, но с такими роутами нужно просто быть осторожнее. Если этот роут в самом конце, а остальные роуты выше не хватают "любой сегмент на первом месте" (а только константы, скажем, /profile), это не должно вызвать серьёзных неприятностей. –  Nov 06 '15 at 21:10
  • Огромное вам спасибо за советы. Просто словами не передать как вам благодарен. Я надеюсь что этот ответ поможет еще многим кто будет искать решение. – bismoney Nov 06 '15 at 21:14
  • D-side, а подскажи пожалуйста, что бы вместо id получить title в виде транслитерации, мне как раз поможет friendly_id? – bismoney Nov 06 '15 at 21:18
  • @bismoney вроде как да, хотя его автор выпустил эту функциональность в виде отдельной библиотеки babosa. –  Nov 06 '15 at 21:20
  • Спасибо! То что нужно. – bismoney Nov 06 '15 at 21:55
  • Привет D-side, подскажи пожалуйста если не занят. Никак не могу уловить логику как обработать в контроллере дату в url. Обновил пост – bismoney Nov 08 '15 at 02:59
  • @bismoney лучше оформить отдельным вопросом, но в целом ответ -- точно так же. Просто в урле будет три сегмента, из которых надо собрать дату (Date). –  Nov 08 '15 at 08:24
  • Честно говоря, так и не понял как быть с датой в урл.. не поможете? http://ru.stackoverflow.com/questions/464629/Дата-в-url-как-реализовать – bismoney Nov 16 '15 at 12:22