首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ActiveModel属性

ActiveModel属性
EN

Stack Overflow用户
提问于 2011-03-29 01:04:37
回答 5查看 12.7K关注 0票数 12

如何获取ActiveRecord属性方法的功能?我有这样一门课:

代码语言:javascript
复制
class PurchaseForm
  include ActiveModel::Validations
  include ActiveModel::Conversion
  extend ActiveModel::Naming

  attr_accessor :name,
                :surname,
                :email

  validates_presence_of :name

  validates_format_of :email, :with => /^[-a-z0-9_+\.]+\@([-a-z0-9]+\.)+[a-z0-9]{2,4}$/i

  def initialize(attributes = {}, shop_name)
    if not attributes.nil?
      attributes.each do |name, value|
      send("#{name}=", value)
    end
  end

  def persisted?
    false
  end
end

我需要做什么,让attributes方法列出PurchaseForm对象中的所有名称和值?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2011-03-29 02:08:07

我已经设法用下面的代码解决了这个问题:

代码语言:javascript
复制
class PurchaseForm
  include ActiveModel::Validations
  include ActiveModel::Conversion
  extend ActiveModel::Naming

  attr_accessor :attributes,
                :name,
                :surname,
                :email

  validates_presence_of :name

  validates_format_of :email, :with => /^[-a-z0-9_+\.]+\@([-a-z0-9]+\.)+[a-z0-9]{2,4}$/i

  def initialize(attributes = {})
    @attributes = attributes
  end

  def persisted?
    false
  end
end
票数 7
EN

Stack Overflow用户

发布于 2015-08-29 05:35:04

以下是重构后的变体:

代码语言:javascript
复制
class PurchaseForm
  include ActiveModel::Model

  def self.attributes
    [:name, :surname, :email]
  end

  attr_accessor *self.attributes

  # your validations

  def to_hash
    self.class.attributes.inject({}) do |hash, key|
      hash.merge({ key => self.send(key) })
    end
  end  
end

现在,您可以轻松地使用这个类:

代码语言:javascript
复制
irb(main):001:0> a = PurchaseForm.new({ name: 'Name' })
=> #<PurchaseForm:0x00000002606b50 @name="Name">
irb(main):002:0> a.to_hash
=> {:name=>"Name", :surname=>nil, :email=>nil}
irb(main):003:0> a.email = 'user@example.com'
=> "user@example.com"
irb(main):004:0> a
=> #<PurchaseForm:0x00000002606b50 @name="Name", @email="user@example.com">
irb(main):005:0> a.to_hash
=> {:name=>"Name", :surname=>nil, :email=>"user@example.com"}

更重要的是,如果您想使此行为可重用,请考虑将.attributes#to_hash方法提取到单独的模块中:

代码语言:javascript
复制
module AttributesHash
  extend ActiveSupport::Concern

  class_methods do
    def attr_accessor(*args)
      @attributes = args
      super(*args)
    end

    def attributes
      @attributes
    end
  end

  included do
    def to_hash
      self.class.attributes.inject({}) do |hash, key|
        hash.merge({ key => self.send(key) })
      end
    end
  end
end

现在,只需将其包含到您的模型中,您就完成了:

代码语言:javascript
复制
class PurchaseForm
  include ActiveModel::Model
  include AttributesHash

  attr_accessor :name, :surname, :email

  # your validations
end
票数 17
EN

Stack Overflow用户

发布于 2016-11-18 23:06:44

#instance_values可以完成这项工作:

代码语言:javascript
复制
class PurchaseForm
  attr_accessor :name, :email

  def attributes
    instance_values
  end
end

输出示例:

代码语言:javascript
复制
purchase.attributes #=> {"name"=>"John", "email"=>"john@example.com"}
票数 14
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5462484

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档