更改rails控制器上的ruby以根据路由嵌套做出不同的响应

时间:2014-01-03 22:21:31

标签: ruby-on-rails ruby

是否可以让控制器在顶级和嵌套级别以标准方式进行交互?或者是否需要配置静态路由?

当我访问第一个地址/ list /:list_id / items时,我希望它遵循nested_index方法,只显示所列项目的子集(属于该列表的项目)。

http://localhost:3000/list/:list_id/items

当我访问下面的(/ items)地址时,我希望它显示整个项目列表。

http://localhost:3000/items

/app/controllers/items_controller.rb

def index
  @Item = Item.all
  respond_to do |format|
    format.html # index.html.erb
    format.json { render json: @Item }
  end
end


def nested_index
  @list = List.find(params[:list_id])
  @items = @list.items.paginate(page: params[:page], per_page: 5)
  respond_to do |format|
    format.html # index.html.erb
    format.json { render json: @list }
  end
end

/config/routes.rb

 AppName::Application.routes.draw do
   resources :list do 
     resources :items
   end
 end
    # Do I need to add further routes here?

2 个答案:

答案 0 :(得分:0)

我个人认为你应该把它分成两个独立的控制器。

控制器的index方法应该只设计一件事。对于嵌套路由,它应该获取适合所选列表的所有项目并将它们传递到适当的视图。在另一个例子中,它正在获取所有项目,并且(可能)将它们传递给完全不同的视图。

看起来你正试图让一个控制器完成两个工作,只是为了控制器的名字。

我建议创建一个apps_controller并使用它来收集所有项目并显示它们,并保留items_controller以供其嵌套使用。

请记住,您不需要在与其交互的模型之后命名控制器......相反,您应该在负责的函数之后命名它。接收用户帐户激活码的控制器可能会更新is_active模型上的User布尔值,但您可以调用此控制器Activations,因为它就是这样做的。

如果控制器之间有很多重叠,您可以将其代码移动到模块中,然后将这些模块包含在两个控制器中。通过这种方式,您可以在保持逻辑分离的同时干掉代码。

请查看这些链接,了解有关代码提取的一些想法:

但在开始将所有代码重构为模块之前...考虑它是否会为您的代码库添加任何内容。它会让事情变得简单吗?它是否使事物更具可读性?除了键入更多的行之外,它能为您节省更多的东西吗?如果重构没有任何好处......就是不要这样做。

答案 1 :(得分:0)

@Jon是对的。这应该分成几个不同的控制器:

# app/controllers/items_controller.rb
class ItemsController < ApplicationController
  # default RESTful actions to operate on lists, for example #index

  def index
    @Item = Item.all

    respond_to do |format|
      format.html
      format.json { render json: @item }
    end
  end
end

# app/controllers/lists_controller.rb
class ListsController < ApplicationController
  # default RESTful actions to operate on lists
end

# app/controllers/lists/items_controllers.rb
class Lists::ItemsController < ApplicationController
  def show
    @list  = List.find(params[:list_id])
    @items = @list.items.paginate(page: params[:page], per_page: 5)

    respond_to do |format|
      format.html
      format.json { render json: @items }
    end
  end
end

路线:

AppName::Application.routes.draw do
  resources :items

  resources :lists do 
    resources :items
  end
end