Rails Namespace vs. Nested Resource

前端 未结 2 2017
一向
一向 2021-01-30 15:21

Let\'s say my app has two models, Foo and Bar.

Foo optionally belongs_to Bar.

Right now I can look at a single Foo, or search for a particular Foo, and the FoosC

相关标签:
2条回答
  • 2021-01-30 15:34

    I think what you're trying to achieve is:

    1. Bar has many Foos
    2. View Foos belonging to Bar
    3. View all Foos regardless of parent.

    You can achieve that with: routes.rb:

    resources :foos
    resources :bars do
      resources :foos, :controller => 'bars/foos'
    end
    

    The route helpers you end up with are:

    • bars_path
    • foos_path
    • bars_foos_path
    • etc, etc, 'rake routes' for the rest =)

    In essence, you end up with:

    • app/BarsController (rails g controller bars)
    • app/FoosController (rails g controller foos)
    • app/bars/FoosController (rails g controller bars/foos)

    In FoosController, you would access foos as usual with:

    @foos = Foos.all
    

    and in bars/FoosController, you would access bar's foos with:

    @foos = @bar.foos
    

    where bar can be pre-retrieved in the bars/foos controller with:

    before_filter :get_client
    
    private
    def get_client
      @bar = Bar.find(params[:bar_id])
    end
    

    Hope this helps. =)

    Edit: As for namespaced routes, I've personally used them when I some of my resources retrieved from a sub-path. For example, if I have an admin section of my site, then I might have the following:

    routes.rb:

    namespace :admin do
      resources :foos
    end
    

    and I create my controller with:

    rails g controller admin/foos
    

    This sets up my foos resource, such that I can access it at "my site url"/admin/foos, and also get helpers such as admin_foos_path.

    0 讨论(0)
  • 2021-01-30 15:35

    There are cons to this approach.

    If you declare a constant, eg. CONST_NAME, in nested resource foos, rails will throw "uninitialized constant ::Foo::CONST_NAME" exception because of its scope algorithm.

    To avoid such behaviour, use:

    resources :foos
    resources :bars do
      scope :module => "bar" do
        resources :foos #, :controller => 'bar/foos' no need to use this now because route will be searched there by default
      end
    end
    

    Now you will not get an exception while using:

    Foo::CONST_NAME
    

    or

    Bar::Foo::CONST_NAME
    
    0 讨论(0)
提交回复
热议问题