用于Ruby中嵌套路由的DRY控制器

时间:2013-04-14 04:12:31

标签: ruby-on-rails ruby dry

我有一个使用以下模型设置的项目。每个->代表一个has_many关系:

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 个答案:

答案 0 :(得分:2)

如果参数总是相同的,你可以创建一个这样的方法

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]

编辑:

另外,为了确保它不会在你的脸上爆炸,你可以

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

并按照要求..通过执行类似

的操作确保目标属于用户
@goals = @user.goals.find(params[:goal_id])

答案 1 :(得分:1)

你总是定义你自己的助手方法

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

您可以将其添加到application_helper,然后在任何视图中使用任意内容。这将创建您在问题中提到的小助手方法。

寻找一个为你做这件事的宝石并没有向我展示任何东西,但你可以用一般的方式自己编写代码。