Ruby on Rails - 控制器

Rails 控制器是应用程序的逻辑中心。它协调用户、视图和模型之间的交互。控制器也是许多重要辅助服务的所在地。

  • 它负责将外部请求路由到内部操作。它能够非常好地处理人性化的 URL。

  • 它管理缓存,这可以使应用程序的性能提高几个数量级。

  • 它管理辅助模块,这些模块可以扩展视图模板的功能,而无需增加代码量。

  • 它管理会话,让用户感觉与我们的应用程序进行了持续交互。

创建控制器的过程非常简单,它与我们之前用于创建模型的过程类似。我们将在这里创建一个控制器 −

library\> rails generate controller Book

请注意,您将 Book 大写并使用单数形式。这是 Rails 范例,每次创建控制器时都应遵循此范例。

此命令完成多项任务,其中以下内容与此处相关 −

  • 它创建一个名为 app/controllers/book_controller.rb

如果您查看 book_controller.rb,您会发现它如下所示 −

class BookController < ApplicationController
end

控制器类继承自 ApplicationController,它是 controllers 文件夹中的另一个文件:application.rb

ApplicationController 包含可以在所有控制器中运行的代码,它继承自 Rails ActionController::Base 类。

目前您无需担心 ApplicationController,因此我们只需在 book_controller.rb 中定义几个方法存根即可。根据您的要求,您可以在此文件中定义任意数量的函数。

将文件修改为如下所示并保存更改。请注意,您可以自行决定为这些方法指定什么名称,但最好指定相关的名称。

class BookController < ApplicationController
   def list
   end
   
   def show
   end
   
   def new
   end
   
   def create
   end
   
   def edit
   end
   
   def update
   end
   
   def delete
   end
   
end

现在让我们逐一实现所有方法。

实现 list 方法

list 方法为您提供数据库中所有书籍的列表。此功能将通过以下代码行实现。在 book_controller.rb 文件中编辑以下行。

def list
    @books = Book.all
end

list 方法中的 @books = Book.all 行告诉 Rails 搜索 books 表并将其找到的每一行存储在 @books 实例对象中。

实现 show 方法

show 方法仅显示有关单本书的更多详细信息。此功能将通过以下代码行实现。

def show
   @book = Book.find(params[:id])
end

show 方法的 @book = Book.find(params[:id]) 行告诉 Rails 仅查找具有 params[:id] 中定义的 id 的书籍。

params 对象是一个容器,可让您在方法调用之间传递值。例如,当您在 list 方法调用的页面上时,您可以单击特定书籍的链接,它会通过 params 对象传递该书籍的 id,以便 show 可以找到特定的书籍。

实现新方法

新方法让 Rails 知道您将创建一个新对象。因此只需在此方法中添加以下代码即可。

def new
    @book = Book.new
    @subjects = Subject.all
end

当您向用户显示页面以获取用户输入时,将调用上述方法。这里第二行从数据库中获取所有主题并将它们放入名为 @subjects 的数组中。

实现 create 方法

使用 HTML 表单获取用户输入后,就可以在数据库中创建记录了。为此,请编辑 book_controller.rb 中的 create 方法以匹配以下内容 −

def create
   @book = Book.new(book_params)
	
   if @book.save
      redirect_to :action => 'list'
   else
      @subjects = Subject.all
      render :action => 'new'
   end
   
end

def book_params
   params.require(:books).permit(:title, :price, :subject_id, :description)
end

第一行创建了一个名为 @book 的新实例变量,该变量保存了由用户提交的数据构建的 Book 对象。book_params 方法用于收集对象 :books 中的所有字段。数据从新方法传递到使用 params 对象创建的方法。

下一行是一个条件语句,如果对象正确保存到数据库,则将用户重定向到 list 方法。如果没有保存,则将用户发送回新方法。redirect_to 方法类似于在网页上执行元刷新:它会自动将您转发到您的目的地,而无需任何用户交互。

然后,如果数据保存失败,则需要 @subjects = Subject.all,并且它与使用新选项的情况类似。

实现 edit 方法

edit 方法看起来与 show 方法几乎相同。这两种方法都用于根据其 id 检索单个对象并将其显示在页面上。唯一的区别是 show 方法不可编辑。

def edit
    @book = Book.find(params[:id])
    @subjects = Subject.all
end

将调用此方法在屏幕上显示可供用户修改的数据。第二行从数据库中获取所有主题并将它们放在名为 @subjects 的数组中。

实现 update 方法

当用户修改数据并希望将更改更新到数据库中时,将在 edit 方法之后调用此方法。update 方法类似于 create 方法,将用于更新数据库中的现有书籍。

def update
   @book = Book.find(params[:id])
	
   if @book.update_attributes(book_param)
      redirect_to :action => 'show', :id => @book
   else
      @subjects = Subject.all
      render :action => 'edit'
   end
   
end

def book_param
   params.require(:book).permit(:title, :price, :subject_id, :description)
end

update_attributes 方法类似于 create 使用的 save 方法,但它不是在数据库中创建新行,而是覆盖现有行的属性。

然后需要 @subjects = Subject.all 行以防它无法成功保存数据,然后它变得类似于 edit 选项。

实现 delete 方法

如果要从数据库中删除记录,则将使用此方法。按如下方式实现此方法。

def delete
    Book.find(params[:id]).destroy
    redirect_to :action => 'list'
end

第一行根据通过 params 对象传递的参数查找分类,然后使用 destroy 方法将其删除。第二行使用 redirect_to 调用将用户重定向到 list 方法。

显示主题的其他方法

假设您想让用户能够浏览基于给定主题的所有书籍。因此,您可以在 book_controller.rb 中创建一个方法来显示所有主题。假设方法名称为 show_subjects

def show_subjects
    @subject = Subject.find(params[:id])
end

最后,您的 book_controller.rb 文件将如下所示 −

class BooksController < ApplicationController

   def list
      @books = Book.all
   end

   def show
      @book = Book.find(params[:id])
   end
  
   def new
      @book = Book.new
      @subjects = Subject.all
   end

   def book_params
      params.require(:books).permit(:title, :price, :subject_id, :description)
   end

   def create
      @book = Book.new(book_params)

      if @book.save
         redirect_to :action => 'list'
      else
         @subjects = Subject.all
         render :action => 'new'
      end
   end
   
   def edit
      @book = Book.find(params[:id])
      @subjects = Subject.all
   end
   
   def book_param
      params.require(:book).permit(:title, :price, :subject_id, :description)
   end
   
   def update
      @book = Book.find(params[:id])
      
      if @book.update_attributes(book_param)
         redirect_to :action => 'show', :id => @book
      else
         @subjects = Subject.all
         render :action => 'edit'
      end
   end
   
   def delete
      Book.find(params[:id]).destroy
      redirect_to :action => 'list'
   end
   
   def show_subjects
      @subject = Subject.find(params[:id])
   end

end

现在保存您的控制器文件。

下一步是什么?

您已经创建了几乎所有将在后端运行的方法。接下来我们将定义操作的路由(URL)。