2013-04-14 6 views
1

У меня есть проект, который настроен на следующие модели. Каждый -> представляет has_many соотношение:DRY контроллеры для вложенных маршрутов в Ruby

Users->Goals->Milestones 

Мои маршруты для Milestones выглядят следующим образом:

user_goal_milestones GET /users/:user_id/goals/:goal_id/milestones(.:format)   milestones#index 
         POST /users/:user_id/goals/:goal_id/milestones(.:format)   milestones#create 
new_user_goal_milestone GET /users/:user_id/goals/:goal_id/milestones/new(.:format)  milestones#new 
edit_user_goal_milestone GET /users/:user_id/goals/:goal_id/milestones/:id/edit(.:format) milestones#edit 
    user_goal_milestone GET /users/:user_id/goals/:goal_id/milestones/:id(.:format)  milestones#show 
         PUT /users/:user_id/goals/:goal_id/milestones/:id(.:format)  milestones#update 
         DELETE /users/:user_id/goals/:goal_id/milestones/:id(.:format)  milestones#destroy 

Я нахожусь во многих из «функций» в контроллере Вехи делать многое из этого:

def index do 
    @user = User.find(params[:user_id]) 
    @goal = Goal.find(params[:goal_id]) 
end 

def edit do 
    @user = User.find(params[:user_id]) 
    @goal = Goal.find(params[:goal_id]) 
end 

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

ответ

2

Если PARAMS всегда то же самое вы можете создать метод, как этого

def set_user_and_goal 
    @user = User.find(params[:user_id]) 
    @goal = Goal.find(params[:goal_id]) 

end 

и положить его в before_filter в верхнем

before_filter :set_user_and_goal 

и установить его на любые действия, которые вы хотите

before_filter :set_user_and_goal, :only => [:edit, :index] 

Edit:

Кроме того, чтобы убедиться, что она не взорвется в вашем лице, вы можете сделать

@user = params.has_key?(:user_id) ? User.find(params[:user_id]) : nil 

и по запросу .. убедитесь, что цель принадлежит пользователю делать что-то вроде

@goals = @user.goals.find(params[:goal_id]) 
+0

Sweet! Это действительно здорово! – CamelBlues

+0

просто убедитесь, что у вас всегда есть: user_id и: goal_id –

+0

Это может привести к неожиданному поведению в приложении. Вы должны проверить, действительно ли прошедшая цель принадлежит переданному пользователю, иначе все может стать уродливым. Пожалуйста, добавьте тесты в свой ответ. – fotanus

1

для Вас всегда определяют свои собственные вспомогательные методы

def goal_milestone(goal) 
    user_goal_milestone(goal.user, goal) 
end 

Вы можете добавить его в свой application_helper, а затем использовать любого в любом из ваших взглядов. Это создало бы небольшие вспомогательные методы, как вы задавали в своем вопросе.

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

+0

Куда бы я положил этого помощника? И как я буду использовать его? – CamelBlues

+0

Обновленный мой ответ, вы можете проверить – fotanus

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