2014-10-27 2 views
2

У моего приложения есть фотомодель. Эти фотографии могут принадлежать нескольким другим классам, например тема, пользователь, тег. Я хотел бы иметь возможность запрашивать все фотографии на основе разных связанных идентификаторов. Я настроил вложенные ресурсы, такие как:Лучшая практика Rails: обработка нескольких отношений в одном контроллере

resources :topics do 
    resources :photos, only: ['index'] 
end 

... 

resources :users do 
    resources :photos, only: ['index'] 
end 

мне интересно, что лучшая практика для обработки этого в контроллере. Моя первоначальная реакция заключается в том, чтобы написать блок if/else, но это очень не рубино.

if !params[:user_id].nil? 
    # query based on user id 
elsif !params[:topic_id].nil? 
    # query based on topic id 

etc. 

Я также обсудили создание действий контроллера и маршрутизации к тем, как user_photos # фото, topic_photos # фото.

Или настройки некоторых новых контроллеров: UserPhotosController, TopicPhotosController

Ни один из них не чувствует себя хорошо, и мне интересно, если кто имеет некоторое представление о том, или если есть общий шаблон дизайна для обработки что-то вроде этого.

Это проект Rails 4, кстати.

+0

Основываясь на описании, вы должны, вероятно, изучить полиморфные ассоциации. Это значительно упростит логику. Вот хорошая концепция [Railscast] (http://railscasts.com/episodes/154-polymorphic-association) по концепции. – engineersmnky

+0

Я не думаю, что я был довольно ясен относительно отношений, но полиморфизм не то, что я ищу.Каждая фотография принадлежит пользователю, а также принадлежит к одной теме. Это своего рода приложение для обмена фотографиями. Я просто хочу отфильтрованную систему запросов, которая не беспорядок. – user3776967

ответ

1

Первые вещи первых, в Rails 4 вы можете использовать concerns:

concern :imageable do 
    resources :photos, only: ['index'] 
end 
resources :topics, concerns: :imageable 
resources :users, concerns: :imageable 

Теперь я вижу два пути идти об этой ситуации.

Вариант A: Move если-то еще к способу, который просто получить гарантируемый, т.е. пользователь, тег, тему и т.д. В вашем PhotosController:

rescue_from ActiveRecord::RecordNotFound, :with => :render_404 

def index 
    respond_with photos 
end 

private 

def photos 
    @photos ||= imageable ? imageable.photos : Photo.all 
end 

# Find and cache the imageable based on the id in params. 
# Using find instead of find_by_id. This is to ensure ActiveRecord::RecordNotFound 
# exception in the case of an invalid id passed, which be handled with render_404 method 
def imageable 
    @imageable ||= begin 
    if id = params[:user_id] 
     User.find(id) 
    elsif id = params[:topic_id] 
     Topic.find(id) 
    end 
    end 
end 

def render_404 
    respond_to do |format| 
    format.html { render template: 'errors/not_found', layout: 'layouts/application', status: 404 } 
    format.all { render nothing: true, status: 404 } 
    end 
end 

Вариант B: Меняйте маршруты в вместо этого:

resources :photos, only: ['index'] do 
    resources :topics 
    resources :users 
end 

, а затем изменить TopicsControllerUsersController, и т.д., соответственно, и тогда вам не нужно создавать UserPhotosController, TopicPhotosController и т. Д.

+0

Мне нравится идея переноса условного метода. Кроме того, не знал о проблемах в маршрутах. Благодарю. – user3776967

1

Если вы можете комбинировать логику контроллера в одном классе контроллера, тогда вы должны это сделать. Я не понимаю, почему выбор, основанный на значениях парамакса, должен быть рубиновым. Кажется, это правильно.

+0

Ну, я беспокоюсь, что есть много потенциальных условий. Я не хочу долго беспорядочно, если, elsif, elsif, elsif, elsif ... – user3776967

1

Это будет хорошо для вас, чтобы использовать это утверждение if.

Еще одна вещь, которую вы можете сделать, - это иметь инструкции if, а затем помещать ваши параметры в хэш. Затем вы можете передать этот хэш в поиск модели, если хотите посмотреть фотографии определенного пользователя по определенной теме.

Пример этого этот ответ здесь: https://stackoverflow.com/a/4480139/2589358

Я нашел, что это был хороший способ, потому что легче управлять, добавив больше Params позже один, а также она выглядит чище.

Смежные вопросы