README.rdoc 5.4 KB
Newer Older
M
Mislav Marohnić 已提交
1 2 3 4 5 6 7 8 9 10
= Active Model -- model interfaces for Rails

Active Model provides a known set of interfaces for usage in model classes.
They allow for Action Pack helpers to interact with non-ActiveRecord models,
for example. Active Model also helps building custom ORMs for use outside of
the Rails framework.

Prior to Rails 3.0, if a plugin or gem developer wanted to have an object
interact with Action Pack helpers, it was required to either copy chunks of
code from Rails, or monkey patch entire helpers to make them handle objects
R
R.T. Lechow 已提交
11
that did not exactly conform to the Active Record interface. This would result
J
José Valim 已提交
12 13 14
in code duplication and fragile applications that broke on upgrades. Active
Model solves this by defining an explicit API. You can read more about the
API in ActiveModel::Lint::Tests.
M
Mislav Marohnić 已提交
15

J
José Valim 已提交
16 17
Active Model also provides the following functionality to have ORM-like
behavior out of the box:
M
Mislav Marohnić 已提交
18 19 20

* Add attribute magic to objects

21 22
    class Person
      include ActiveModel::AttributeMethods
23

24 25
      attribute_method_prefix 'clear_'
      define_attribute_methods [:name, :age]
26

27
      attr_accessor :name, :age
28

29 30 31 32
      def clear_attribute(attr)
        send("#{attr}=", nil)
      end
    end
33

M
Mislav Marohnić 已提交
34 35
    person.clear_name
    person.clear_age
36

37
  {Learn more}[link:classes/ActiveModel/AttributeMethods.html]
38

M
Mislav Marohnić 已提交
39
* Callbacks for certain operations
M
Mikel Lindsaar 已提交
40

41
    class Person
M
Mikel Lindsaar 已提交
42 43
      extend ActiveModel::Callbacks
      define_model_callbacks :create
44

M
Mikel Lindsaar 已提交
45
      def create
46
        run_callbacks :create do
M
Mikel Lindsaar 已提交
47 48 49 50
          # Your create action methods here
        end
      end
    end
51

M
Mislav Marohnić 已提交
52 53
  This generates +before_create+, +around_create+ and +after_create+
  class methods that wrap your create method.
54

55
  {Learn more}[link:classes/ActiveModel/CallBacks.html]
56

M
Mislav Marohnić 已提交
57
* Tracking value changes
58

M
Mislav Marohnić 已提交
59
  The ActiveModel::Dirty module allows for tracking attribute changes:
M
Mikel Lindsaar 已提交
60

61 62
    person = Person.new
    person.name # => nil
M
Mikel Lindsaar 已提交
63 64 65 66
    person.changed? # => false
    person.name = 'bob'
    person.changed? # => true
    person.changed # => ['name']
67
    person.changes # => { 'name' => [nil, 'bob'] }
M
Mikel Lindsaar 已提交
68 69 70
    person.name = 'robert'
    person.save
    person.previous_changes # => {'name' => ['bob, 'robert']}
71

72 73
  {Learn more}[link:classes/ActiveModel/Dirty.html]

M
Mislav Marohnić 已提交
74
* Adding +errors+ interface to objects
75

M
Mislav Marohnić 已提交
76 77
  Exposing error messages allows objects to interact with Action Pack
  helpers seamlessly.
78

79
    class Person
80

81 82 83
      def initialize
        @errors = ActiveModel::Errors.new(self)
      end
84

85 86
      attr_accessor :name
      attr_reader   :errors
87

88
      def validate!
V
Vijay Dev 已提交
89
        errors.add(:name, "can not be nil") if name.nil?
90
      end
91

C
Carlos Antonio da Silva 已提交
92
      def self.human_attribute_name(attr, options = {})
93 94 95
        "Name"
      end
    end
96

97
    person.errors.full_messages
V
Vijay Dev 已提交
98
    # => ["Name can not be nil"]
99

100
    person.errors.full_messages
V
Vijay Dev 已提交
101
    # => ["Name can not be nil"]
102 103

  {Learn more}[link:classes/ActiveModel/Errors.html]
104

M
Mislav Marohnić 已提交
105
* Model name introspection
106

107 108 109
    class NamedPerson
      extend ActiveModel::Naming
    end
110

P
Paco Guzman 已提交
111 112
    NamedPerson.model_name        # => "NamedPerson"
    NamedPerson.model_name.human  # => "Named person"
113 114 115

  {Learn more}[link:classes/ActiveModel/Naming.html]

M
Mislav Marohnić 已提交
116
* Observer support
117

M
Mislav Marohnić 已提交
118 119 120
  ActiveModel::Observers allows your object to implement the Observer
  pattern in a Rails App and take advantage of all the standard observer
  functions.
121

122
  {Learn more}[link:classes/ActiveModel/Observer.html]
123

M
Mislav Marohnić 已提交
124
* Making objects serializable
125

M
Mislav Marohnić 已提交
126 127
  ActiveModel::Serialization provides a standard interface for your object
  to provide +to_json+ or +to_xml+ serialization.
128

129 130 131 132
    s = SerialPerson.new
    s.serializable_hash   # => {"name"=>nil}
    s.to_json             # => "{\"name\":null}"
    s.to_xml              # => "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<serial-person...
133

134
  {Learn more}[link:classes/ActiveModel/Serialization.html]
M
Mikel Lindsaar 已提交
135

M
Mislav Marohnić 已提交
136
* Internationalization (i18n) support
137 138 139 140

    class Person
      extend ActiveModel::Translation
    end
141

M
Mislav Marohnić 已提交
142
    Person.human_attribute_name('my_attribute')
P
Paco Guzman 已提交
143
    # => "My attribute"
144

145
  {Learn more}[link:classes/ActiveModel/Translation.html]
146

M
Mislav Marohnić 已提交
147
* Validation support
148 149 150 151 152 153 154 155 156 157 158

   class Person
     include ActiveModel::Validations

     attr_accessor :first_name, :last_name

     validates_each :first_name, :last_name do |record, attr, value|
       record.errors.add attr, 'starts with z.' if value.to_s[0] == ?z
     end
   end

159 160
   person = Person.new
   person.first_name = 'zoolander'
P
Paco Guzman 已提交
161
   person.valid?  # => false
162 163

  {Learn more}[link:classes/ActiveModel/Validations.html]
164

M
Mislav Marohnić 已提交
165
* Custom validators
166

C
Carlos Antonio da Silva 已提交
167
   class ValidatorPerson
168 169 170 171
     include ActiveModel::Validations
     validates_with HasNameValidator
     attr_accessor :name
   end
172

173 174
   class HasNameValidator < ActiveModel::Validator
     def validate(record)
C
Carlos Antonio da Silva 已提交
175
       record.errors[:name] = "must exist" if record.name.blank?
176 177
     end
   end
178

179
   p = ValidatorPerson.new
P
Paco Guzman 已提交
180 181
   p.valid?                  # =>  false
   p.errors.full_messages    # => ["Name must exist"]
182
   p.name = "Bob"
P
Paco Guzman 已提交
183
   p.valid?                  # =>  true
184 185

  {Learn more}[link:classes/ActiveModel/Validator.html]
J
José Valim 已提交
186

187 188 189

== Download and installation

W
Waynn Lue 已提交
190
The latest version of Active Model can be installed with RubyGems:
191 192 193 194 195

  % [sudo] gem install activemodel

Source code can be downloaded as part of the Rails project on GitHub

196
* https://github.com/rails/rails/tree/master/activemodel
197 198 199 200


== License

201 202 203
Active Model is released under the MIT license:

* http://www.opensource.org/licenses/MIT
204 205 206 207 208 209 210 211 212 213 214


== Support

API documentation is at

* http://api.rubyonrails.org

Bug reports and feature requests can be filed with the rest for the Ruby on Rails project here:

* https://github.com/rails/rails/issues