Rails Virtus vs ActiveModel 应该选哪个?

ericguo · 发布于 2014年04月12日 · 最后由 ericguo 回复于 2014年04月13日 · 2319 次阅读
Eda824

读了重构臃肿 ActiveRecord 模型的 7 种方式这篇相当经典的文章,我注意到了文中提到的Virtus这个gem,可以相当漂亮的解决一次表单更新多个model这样的情况,比如这段摘自文章里面的代码:

class Signup
  include Virtus

  extend ActiveModel::Naming
  include ActiveModel::Conversion
  include ActiveModel::Validations

  attr_reader :user
  attr_reader :company

  attribute :name, String
  attribute :company_name, String
  attribute :email, String

  validates :email, presence: true
  # … more validations …

  # Forms are never themselves persisted
  def persisted?
    false
  end

  def save
    if valid?
      persist!
      true
    else
      false
    end
  end

private

  def persist!
    @company = Company.create!(name: company_name)
    @user = @company.users.create!(name: name, email: email)
  end
end

这样用到SignUp的controller就可以非常的精简:

class SignupsController < ApplicationController
  def create
    @signup = Signup.new(params[:signup])

    if @signup.save
      redirect_to dashboard_path
    else
      render "new"
    end
  end
end

但是我注意到这篇经典文章写于2012年,然后2013年Rails 4引入了ActiveModel::Model,所以似乎第一段代码也可以用ActiveModel::Model这样实现:

class Signup
  include ActiveModel::Model

  attr_accessor(
    :company_name,
    :email,
    :name,
  )

  attr_reader :user
  attr_reader :company

  validates :company_name, presence: true
  validates :email, presence: true, email: true
  validates :name, presence: true

  def save
    if valid?
      persist!
      true
    else
      false
    end
  end

private
  def persist!
    @company = Company.create!(name: company_name)
    @user = @company.users.create!(name: name, email: email)
  end
end

显然后一种Signup的实现更短,而且persisted?方法也在ActiveModel::Model里面定义了,还能省不少行数,且不用引入一个额外的gem,但是这样用真的没有啥其他问题么?

共收到 2 条回复
2ed86d

attribute :age, Integer 要的不是字符串呢

2楼 已删除
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册