ActiveRecord带有一组强大的验证器和其他功能,用于持久数据模型的属性。 另一方面,表单是当今Web应用程序中最古老,最重要的构建块之一,它是用户输入的基本界面。 Rails提供的两个表单助手中,“ form_for”还假设您正在使用某种持久化对象。 因此,它可以充分利用所有活动记录功能,即验证。
这对于具有数据库支持表示形式的持久对象非常有用。 但是,当您需要一个不能反映某种持久记录的复杂表格时会发生什么呢?
在本教程中,我将讨论该问题的可能解决方案以及如何在Rails 4(活动模型)中实现一个解决方案。
在本教程中,我们将使用表单来构建应用程序,用户可以在其中添加一些反馈,然后将其保存到数据库中。 该应用程序还将具有验证和视图,完全是您为数据库支持的模型创建验证和视图的方式,但是随后我们将对模型进行一些更改以使其成为无表的。 并且所有功能必须按原样运行,而无需进行任何进一步的更改。 没有用于反馈的更新,删除或查找操作。
第一要务
对于本教程,我假设您对Rails框架有基本的了解,并且可以轻松创建或生成基本的控制器,模型和视图。 我假设您也对路由和验证的工作方式有所了解。 在撰写本教程时,我正在使用Rails 4.2.5和SQLite 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