我有一个应用程序可以将所有内容置于Project
下。所有视图都要求项目可用。这允许我使用current_project
方法:
current_project = current_user.projects.find(params[:project_id)
虽然这很方便,但这意味着我的路由总是必须在项目范围内,我不能使用浅路由。当你有四个嵌套级别时,这可能会很糟糕。
resources :projects do
resources :posts do
resources :attachments
resources :comments do
resources :attachments
end
end
end
这种嵌套意味着复杂的路线和复杂的测试:
form_for [@project, @post, @comment, @attachment] ...
这也意味着很多重复,因为像attachments
这样的多态模型必须适用于嵌套在不同级别的posts
和comments
。
form_for [@project, @attachable, @attachment] # ... for posts
form_for [@project, @post, @attachable, @attachment] # ... for comments
所以我转而使用浅路线。这是一种解脱,但这有另一个令人讨厌的副作用:
current_project
不再容易实现。例如,要获得Attachment
,我需要经历三个父母:
@attachment.comment.post.project
由于所有观点都需要它,我几乎每次都需要这样做。
@project = @post.project
@project = @comment.post.project
@project = @attachment.comment.post.project
是否有一些中间地带,我可以使用方便的current_project
方法,而不必将我的路线嵌套4级?我也不想使用子域名。
答案 0 :(得分:1)
再看一下,我认为最好将current_project_id保存到users表中,以便当有人切换项目时更新他们的记录。然后,你的current_project方法只是
#application.rb
def current_project
@current_project ||= current_user.current_project
end
您需要添加
#user.rb
belongs_to :current_project, :class_name => "Project"
并且,在任何页面加载时,您总是知道您正在处理哪个项目,只需使用此方法查看users表。
答案 1 :(得分:0)
#in app/controllers/application.rb
def current_project
unless @current_project
@current_project = (@post && @post.project) || (@comment && @comment.post.project) || (@attachment && @attachment.comment.post.project)
end
@current_project
end
我在方法中使用实例变量@current_project,这样如果在单个动作/渲染中多次调用current_project,它只需要进行一次计算:随后它将只从@current_project中读出它。 / p>
答案 2 :(得分:0)
我建议添加一个before_action,将@current_project加载到每个控制器。