2014-02-13 54 views
5

我想知道什么是解决以下问题的正确方法。如何管理嵌套和非嵌套资源

我有两个型号:

Publisher and Issue. Publisher has_many issues. 

我要同时管理从发布列表和问题清单的问题。

例如:

  • 对发布者列表中,用户可以点击放置在每个出版商附近链接“问题”。然后他转到问题列表,但仅针对正确的发布者进行过滤。他可以点击“创建新的问题”,去形成新的问题。在这种形式上,我不需要向他展示选择列表以选择发布者

  • 关于问题列表用户可以单击“创建新问题”并转到表单,但是这次他应该从select中选择发布者,这将是与创建的问题有关。

简而言之,我需要针对问题和发布商问题的粗暴行动。

首先,我尽量做到:

resources :issues 

    resources :publishers do 
    resources :issues 
    end 

,并在发行控制器:

before_filter :find_issue 

def find_issue 
@publisher = Publisher.find(params[:publisher_id]) if params[:publisher_id] 
@issues = @publisher ? @publisher.issues : Issue 
end 

,但我必须做出许多假设条件我的意见和控制器。

例如,如果问题是从发布者创建的,在成功时我想重定向到publisher_issues_path而不是issue_path,反之亦然。与“回到列表”等类似的所有链接都存在同样的问题。所以代码在我看来不是很透明。

现在我想知道使用命名空间。

namespace :publishers, do 
    resources :issues 
end 

和使

# app/controllers/publishers/issues_controller.rb 
module Publishers 
    class IssuesController < ApplicationController 
    # actions that expect a :publisher_id param 
    end 
end 

# app/controllers/issues_controller.rb 
class IssuesController < ApplicationController 
    # your typical actions without any publisher handling 
end 

,并为这两个控制器操作单独的视图。

有没有更好的或更清洁的方法来解决这类问题?我想尽可能让代码变干。 非常感谢您的回复。

回答

3

路线:

resources :issues 
resources :publishes do 
    resources :issues 
end 

控制器:

class IssuesController < ApplicationController 
    before_filter :build_issue, only: [:new, :create] 
    before_filter :load_issue, only: [:show, :edit, :update, :destroy] 

    def index 
    @issues = issues.page(params[:page]) 
    end 

    ... all other actions will have access to @issue 

private 
    def issues 
    if params[:publisher_id].present? 
     Publisher.find(params[:publisher_id]).issues 
    else 
     Issue 
    end 
    rescue ActiveRecord::RecordNotFound 
    redirect_to issues_path(alert: 'Publisher not found') 
    end 

    def build_issue 
    @issue = issues.new(issue_params) 
    end 

    def load_issue 
    @issue = issues.find(params[:id]) 
    rescue ActiveRecord::RecordNotFound 
    redirect_to issues_path(alert: 'Issue not found') 
    end 

    def issue_params 
    # whitelisted attributes goes here 
    end 
end 

要避免使用条件,使用的行为,而不是完整的命名路径,即:

redirect_to action: :index 
link_to 'Issues', {action: :index}