Rails 4中的非ActiveRecord模型

ActiveRecord带有一组强大的验证器和其他功能,用于持久数据模型的属性。 另一方面,表单是当今Web应用程序中最古老,最重要的构建块之一,它是用户输入的基本界面。 Rails提供的两个表单助手中,“ form_for”还假设您正在使用某种持久化对象。 因此,它可以充分利用所有活动记录功能,即验证。

这对于具有数据库支持表示形式的持久对象非常有用。 但是,当您需要一个不能反映某种持久记录的复杂表格时会发生什么呢?

在本教程中,我将讨论该问题的可能解决方案以及如何在Rails 4(活动模型)中实现一个解决方案。

在本教程中,我们将使用表单来构建应用程序,用户可以在其中添加一些反馈,然后将其保存到数据库中。 该应用程序还将具有验证和视图,完全是您为数据库支持的模型创建验证和视图的方式,但是随后我们将对模型进行一些更改以使其成为无表的。 并且所有功能必须按原样运行,而无需进行任何进一步的更改。 没有用于反馈的更新,删除或查找操作。

第一要务

对于本教程,我假设您对Rails框架有基本的了解,并且可以轻松创建或生成基本的控制器,模型和视图。 我假设您也对路由和验证的工作方式有所了解。 在撰写本教程时,我正在使用Rails 4.2.5SQLite 3.8.10.2

介绍

在许多情况下,当您拥有一个像典型的ActiveRecord模型那样运行的类,但又不想将数据持久存储到数据库中时。 例如,您可能有联系表或更复杂的内容,例如投诉或反馈表。

在这种情况下,要解决此问题,一种方法是使用form_tag helper方法,该方法为您提供了自定义表单字段,这些字段可以执行所需的操作,而不必将它们与任何模型绑定在一起。

这很好用,但是如果要处理多个字段, form_tag会很快变得繁琐,因为需要自己命名多个属性及其验证,因此要处理和维护多个字段。 很快,您的控制器最终将处理大量的逻辑和大量的形式参数,这可能不是理想的解决方案。

如果我们可以以某种方式将相同的form_for与模型以及模型附带的所有验证和其他好处一起使用,而不需要使用数据库支持的其属性表示,那么它将是一种更清洁,更灵活的方法。

Rails正是提供了这种解决方案: Active Model( 活动模型) ,它与普通模型一样,但是没有表。 它提供了完全相同的简便验证方法以及ActiveRecord附带的几乎所有其他好东西。 它可以帮助您保持应用程序结构的一致性,因为无论如何您都使用模型来表示应用程序中的对象,可以免费使用路由,并且使用form_for像以前一样轻松地进行表单构建。

首先创建一个新的应用程序

在此步骤中,我们将在本教程中生成一个虚拟应用程序。

步骤1:建立

启动您的终端并键入以下命令以创建一个新的应用程序:

# Create a basic Rails App
rails new tableless
cd tableless

# Create a Controller with only new, create & success Actions
rails generate controller feedbacks new create success --skip-routes

# Create a Model
rails generate model feedback name:string email:string address:string message:text suggestion:text

这就是目录结构的外观。

目录结构

步骤2:编辑

在这里,我将为您需要填充的所有文件提供代码段。 该代码是不言自明的。 您可以从链接到此文章的GitHub存储库下载此应用,也可以按照我的步骤自行创建一个应用。

/config/ routes.rb

resources :feedbacks, :only => [:new, :create]
get 'feedbacks/success' => 'feedbacks#success', as: :success

→/app/views/feedbacks/success.html.erb

<h1 id="notice"><%= notice %></h1>
<br>
<%= link_to 'Submit New Feedback', new_feedback_path %>

→/ app / views / feedbacks / new.html.erb

<h1>New Feedback</h1>


<%= form_for(@feedback) do |f| %>
 <% if @feedback.errors.any? %>
   <div id="error_explanation">
     <h2><%= pluralize(@feedback.errors.count, "error") %> prohibited this feedback from being saved:</h2>
     <ul>
     <% @feedback.errors.full_messages.each do |message| %>
       <li><%= message %></li>
     <% end %>
     </ul>
   </div>
 <% end %>


 <div class="field">
   <%= f.label :name %><br>
   <%= f.text_field :name %>
 </div>

 <div class="field">
   <%= f.label :email %><br>
   <%= f.text_field :email %>
 </div>

 <div class="field">
   <%= f.label :address %><br>
   <%= f.text_field :address %>
 </div>

 <div class="field">
   <%= f.label :message %><br>
   <%= f.text_area :message %>
 </div>

 <div class="field">
   <%= f.label :suggestion %><br>
   <%= f.text_area :suggestion %>
 </div>

 <div class="actions">
   <%= f.submit %>
 </div>

<% end %>

<%= link_to 'Back', feedbacks_path %>

→/app/controllers/feedbacks_controller.rb

class FeedbacksController < ApplicationController

def new
    @feedback = Feedback.new
end

def create
	@feedback = Feedback.new(feedback_params)
	respond_to do |format|
		if @feedback.save
			format.html { redirect_to success_path, notice: 'Feedback was successfully submitted.' }
		else
			format.html { render :new }
		end
	end
 end

 def success
 end

private

   def feedback_params
     params.require(:feedback).permit(:name, :email, :address, :message, :suggestion)
   end

end

→/ app / models / feedbacks.rb

class Feedback < ActiveRecord::Base

    # fields validation for the database.
	validates :name, presence: true
	validates :email, presence: true, length: {in:5..255}
	validates :address, presence: true
	validates :message, presence: true
	validates :suggestion, presence: true

end

步骤3:部署

要将其部署在本地服务器上,首先需要运行以下命令以在系统中创建数据库。

cd tableless/
rake db:migrate

如果到目前为止,您已经按照本教程进行了操作,那么上面的命令将默认创建一个sqlite3数据库。 要对其进行更改,您可以跳转到database.yml在本教程中,我将使用sqlite3。

现在,在终端中运行rails s ,您应该会看到类似的内容。

控制台日志

这样,您应该可以成功运行虚拟应用程序。

步骤4:测试

现在该测试我们刚刚创建的内容了。 在浏览器中点击此路由,检查是否一切正常: http://localhost:3000/feedbacks/new

反馈页面

您应该看到上面的表格。 现在按提交按钮,而不填写任何字段,以检查验证是否正常。

反馈错误

大。 如上所述,您应该看到六个验证错误。 现在,我们可以尝试填写适当的值并提交表格。

成功的反馈

您应该在屏幕上看到类似的内容。 让我们检查数据库中刚刚输入的记录。

打开终端 ,进入项目目录,然后输入以下命令。

  • rails db在控制台中启动数据库客户端。
  • SQLite> .tables中的所有表(默认情况下选择DB)。
  • SQLite> .headers on可以在结果中显示列名称
  • SQLite> select * from feedbacks; 查看数据库中的所有反馈。
查看数据库中的所有反馈

在这里,我们可以看到反馈已成功保存在数据库中。 如果查看日志,还可以找到INSERT查询。

查看数据库日志

至此,我们的测试结束了。 现在一切似乎都正常,让我们进入解决方案。

解决方案

步骤1:实施

要实现Active Model,您需要做的第一件事就是删除反馈模型对< ActiveRecord::Base的继承,因为我们不希望该模型再具有数据库后端。

一旦执行此操作,我们的表单将不再起作用,因为验证器由ActiveRecord提供。 但是,在下一行添加include ActiveModel::Model应该可以还原所有内容。

您的模型现在应该看起来像这样。

class Feedback 
    include ActiveModel::Model

第二件事是添加attr_accessor来生成所有属性的getter和setter方法,如下所示。

attr_accessor :name, :email, :address, :message, :suggestion

现在,模型的最终结果应如下所示。

class Feedback 

    include ActiveModel::Model
    attr_accessor :name, :email, :address, :message, :suggestion

    # fields validation for the database.
    validates :name, presence: true
    validates :email, presence: true, length: {in:5..255}
	validates :address, presence: true
	validates :message, presence: true
	validates :suggestion, presence: true

end

修复模型不足以使我们的应用程序表现出我们想要的行为。 控制器仍然希望通过create方法将接收到的数据对象保存到数据库中。 @feedback.save无法使用,因为我们没有数据库后端来保存新的反馈信息。

我们可以通过将@feedback.save更改为@feedback.valid?来解决此问题@feedback.valid? 由于我们现在仅在模型中执行验证,并且基于此成功事件,您可以在此代码块内执行任何首选任务,即发送通知,发送电子邮件或日志事件等。

class FeedbacksController < ApplicationController

def create
    @feedback = Feedback.new(feedback_params)
	respond_to do |format|
		if @feedback.valid?
            
            # Something interesting can be done here 
            # - send notifications
            # - send email
            # - log events
            
            format.html { redirect_to success_path, notice: 'Feedback was successfully submitted.' }
		
        else
			
            format.html { render :new }
		
        end
	end
 end

步骤2:测试

让我们重做我们之前执行的测试。

点击路由http://localhost:3000/feedbacks/new并提交 无需填写任何字段的表格。 所有的验证都应该像之前那样工作。

测试反馈提交

大。 现在,我们可以尝试提交具有有效值的表单。

提交具有有效值的表格

接下来,您将获得同样的成功信息。

成功提交反馈

现在,我们需要检查的最后一件事是数据库。

为此,打开您的终端 ,转到您的项目目录,然后键入以下命令。

  • rails db在控制台中启动数据库客户端。
  • SQLite> .tables中的所有表(默认情况下选择DB)。
  • SQLite> .headers on可以在结果中显示列名称
  • SQLite> select * from feedbacks以查看数据库中的所有反馈。

这次,由于我们的模型没有任何数据库表支持,因此您将在表中找不到新提交的值。

数据库中没有值

如果您检查控制台日志,我们也不会再看到INSERT查询。

控制台日志

结论

这样就完成了ActiveModel ,我们看到了创建无表模型的难易程度。 ActiveModel进行了重大改进,因此您可以期待即将发布的Rails版本中的一些更改。

为了使事情简单明了,我们仅在本教程中使用了验证和属性分配。 但是,请查看包含GitHub上ActiveModel代码的目录。

从列表中我们可以看到,ActiveModel还包括用于属性方法,序列化,回调和脏跟踪等的类。 这样,您可以随时关注即将发布的功能并熟悉其他功能。

翻译自: https://code.tutsplus.com/tutorials/non-activerecord-models-in-rails-4--cms-25452

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值