Rails之表单验证

创建一个新项目,设置mysql数据库

rails new demo -d mysql
cd demo
rake db:create

用脚手架工具创建表单及数据库

rails generate scaffold Person name:string secret:string country:string email:string description:text can_send_email:boolean graduation_year:integer body_temperature:float price:decimal birthday:date favorite_time:time
rake db:migrate
rails server -d

编辑app/model/person.rb代码如下,实现表单验证功能

class Person < ActiveRecord::Base
  attr_accessible :birthday, :body_temperature, :can_send_email, :country, :description, :email, :favorite_time, :graduation_year, :name, :price, :secret

  #表单内容必须填写
  validates_presence_of :name, :message => "姓名必须填写"
  validates_presence_of :graduation_year, :message => "毕业年份必须填写"
  validates_presence_of :description, :message => "写一点自我介绍吧"
  #表单信息长度设置
  validates_length_of :secret, :in => 6..12, :message => "密码长度必须是6~12之间"
  #表单内容格式验证
  validates_format_of :secret, :with => /[0-9]/, :message => "密码至少需要包含数字,大写字母及小写字母"
  validates_format_of :secret, :with => /[A-Z]/, :message => "密码至少需要包含数字,大写字母及小写字母"
  validates_format_of :secret, :with => /[a-z]/, :message => "密码至少需要包含数字,大写字母及小写字母"
  #表单范围验证
  validates_inclusion_of :country, :in => ['Canada', 'Mexico', 'UK', 'USA'], :message => "国家在'Canada','Mexico','UK','USA'中选择"
  #邮箱格式验证
  validates_presence_of :email, :if => :require_email_presence?
  validates_format_of :email, :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i, :if => :require_email_presence?, :message => "邮箱格式不>正确"
  #数据唯一性保证
  validates_uniqueness_of :email, :case_sensitive => false, :message => "邮箱已被占用"
  #多个数据规则验证
  validates_numericality_of :graduation_year, :allow_nil => true, :greater_than => 1920, :less_than_or_equal_to => Time.now.year, :only_integer => true, :message => "毕业年份不正确"
  #日期范围验证
  validates_inclusion_of :birthday, :in => Date.civil(1900, 1, 1) .. Date.today, :message => "日期必须是1900年1月1日到今天之间"
  #自定义验证
  validate :description_length_words

  #条件验证
  def require_email_presence?
    self.can_send_email
  end

  #自定义验证
  def description_length_words
    # only do this validation if description is provided
    unless self.description.blank? then
      # simple way of calculating words: split the text on whitespace
      num_words = self.description.split.length
      if num_words < 5 then
        self.errors.add(:description, "介绍必须是5个英文词以上")
      elsif num_words > 50 then
        self.errors.add(:description, "介绍控制在50个词以下")
      end
    end
  end
end

可以通过访问http://127.0.0.1:3000/people检测效果,上面是在测试环境运行

#编辑 config/environments/production.rb 文件,配置如下
config.serve_static_assets = true
config.assets.compile = true

 执行rails server -e production运行在生产环境下,使用生产环境的数据库

 

接着添加文件上传功能,首先需要为数据表增加头像字段

rails generate migration add_photo_extension_to_person

class AddPhotoExtensionToPerson < ActiveRecord::Migration
  def change
    add_column :people, :extension, :string
  end
end

rake db:migrate RAILS_ENV="production"修改数据表

修改model如下

class Person < ActiveRecord::Base
  attr_accessible :birthday, :body_temperature, :can_send_email, :country, :description, :email, :favorite_time, :graduation_year, :name, :price, :secret, :photo

  after_save :store_photo

  def photo=(file_data)
    unless file_data.blank?
      @file_data = file_data
      self.extension = file_data.original_filename.split('.').last.downcase
    end
  end
  def has_photo?
    File.exists? photo_filename
  end
  PHOTO_STORE = File.join Rails.root, 'public', 'photo_store'
  def photo_filename
    File.join PHOTO_STORE, "#{id}.#{extension}"
  end
  def photo_path
    "/photo_store/#{id}.#{extension}"
  end

private
  # 数据库操作完毕后将文件存入文件系统
  def store_photo
    if @file_data
      # 创建文件夹 
      FileUtils.mkdir_p PHOTO_STORE
      # write out the image data to the file
      File.open(photo_filename, 'wb') do |f|
        f.write(@file_data.read)
      end
      # ??
      @file_data = nil
    end
  end
end

增加_form.html.erb文件添加如下内容

#修改
<%= form_for(@person, :html => { :multipart => true }) do |f| %>

#添加
  <div class="field">
    <%= f.label :photo %><br />
    <%= f.file_field :photo %>
  </div>

添加show.html.erb文件如下

<p>
  <b>Photo:</b>
  <% if @person.has_photo? %>
  <%= image_tag @person.photo_path %>
  <% else %>
  No photo.
  <% end %>
</p>

猜你喜欢

转载自ciaos.iteye.com/blog/1860065