Slide 1

Slide 1 text

Active Model l escrevendo aplicações melhores com

Slide 2

Slide 2 text

http://pragprog.com/book/ppmetr/metaprogramming-ruby

Slide 3

Slide 3 text

Rails 2.3.2

Slide 4

Slide 4 text

Active Record

Slide 5

Slide 5 text

Validações

Slide 6

Slide 6 text

obj = MyClass.new obj.attr = 'test' puts obj.valid? # => true obj.attr = 'tst' puts obj.valid? # => false

Slide 7

Slide 7 text

require 'activerecord' ActiveRecord::Base # autoload all modules class MyClass def save; end def save!; end def new_record?; true; end include ActiveRecord::Validations attr_accessor :attr validates_length_of :attr, :minimum => 4 end

Slide 8

Slide 8 text

“I had to go through some hoops to make this code work.” Paolo Perrotta Metaprogramming Ruby

Slide 9

Slide 9 text

require 'activerecord' ActiveRecord::Base # autoload all modules class MyClass def save; end def save!; end def new_record?; true; end include ActiveRecord::Validations attr_accessor :attr validates_length_of :attr, :minimum => 4 end What? ActiveRecord::Base # autoload all modules

Slide 10

Slide 10 text

require 'activerecord' ActiveRecord::Base # autoload all modules class MyClass def save; end def save!; end def new_record?; true; end include ActiveRecord::Validations attr_accessor :attr validates_length_of :attr, :minimum => 4 end def save; end def save!; end LOL

Slide 11

Slide 11 text

require 'activerecord' ActiveRecord::Base # autoload all modules class MyClass def save; end def save!; end def new_record?; true; end include ActiveRecord::Validations attr_accessor :attr validates_length_of :attr, :minimum => 4 end def new_record?; true; end trolling

Slide 12

Slide 12 text

require 'activerecord' ActiveRecord::Base # autoload all modules class MyClass def save; end def save!; end def new_record?; true; end include ActiveRecord::Validations attr_accessor :attr validates_length_of :attr, :minimum => 4 end include ActiveRecord::Validations attr_accessor :attr validates_length_of :attr, :minimum => 4 there we go!

Slide 13

Slide 13 text

“However, that wasn’t too much work in exchange for a flexible set of validation Class Macros.” Paolo Perrotta Metaprogramming Ruby

Slide 14

Slide 14 text

work? not too much

Slide 15

Slide 15 text

require 'activerecord' ActiveRecord::Base # autoload all modules class MyClass def save; end def save!; end def new_record?; true; end include ActiveRecord::Validations attr_accessor :attr validates_length_of :attr, :minimum => 4 end ActiveRecord::Base # autoload all modules def save; end def save!; end def new_record?; true; end

Slide 16

Slide 16 text

require 'activerecord' ActiveRecord::Base # autoload all modules class MyClass def save; end def save!; end def new_record?; true; end include ActiveRecord::Validations attr_accessor :attr validates_length_of :attr, :minimum => 4 end include ActiveRecord::Validations attr_accessor :attr validates_length_of :attr, :minimum => 4

Slide 17

Slide 17 text

work! too much

Slide 18

Slide 18 text

nisso? como chegar

Slide 19

Slide 19 text

Source diving!

Slide 20

Slide 20 text

Active Model

Slide 21

Slide 21 text

@cantoniodasilva Carlos Antonio

Slide 22

Slide 22 text

No content

Slide 23

Slide 23 text

Devise maintainer SimpleForm maintainer

Slide 24

Slide 24 text

Rails commiter

Slide 25

Slide 25 text

guru SC

Slide 26

Slide 26 text

Active Model aplicações melhores escrevendo com

Slide 27

Slide 27 text

Rails 2.3

Slide 28

Slide 28 text

Active Record VALIDAÇÕES SERIALIZAÇÃO JSON/XML ...

Slide 29

Slide 29 text

Active Resource VALIDAÇÕES SERIALIZAÇÃO JSON/XML ...

Slide 30

Slide 30 text

Mongoid VALIDAÇÕES ? SERIALIZAÇÃO ? ...

Slide 31

Slide 31 text

MyClass VALIDAÇÕES ? SERIALIZAÇÃO ? ...

Slide 32

Slide 32 text

require 'activerecord' ActiveRecord::Base # autoload all modules class MyClass def save; end def save!; end def new_record?; true; end include ActiveRecord::Validations attr_accessor :attr validates_length_of :attr, :minimum => 4 end

Slide 33

Slide 33 text

! DRY

Slide 34

Slide 34 text

Frágil

Slide 35

Slide 35 text

Rails 3

Slide 36

Slide 36 text

Rails 3 Rewrite Everything!

Slide 37

Slide 37 text

Active Model

Slide 38

Slide 38 text

Active Model VALIDAÇÕES SERIALIZAÇÃO JSON/XML ...

Slide 39

Slide 39 text

Active Record include ActiveModel::*

Slide 40

Slide 40 text

module ActiveRecord class Base extend ActiveModel::Naming # Uses ActiveModel::Translation extend Translation # Uses ActiveModel::MassAssignmentSecurity include AttributeAssignment include ActiveModel::Conversion # Uses ActiveModel::Validations include Validations # Uses ActiveModel::AttributeMethods include AttributeMethods # Uses ActiveModel::Callbacks include Callbacks include ActiveModel::Observing include ActiveModel::SecurePassword # Uses ActiveModel::Serialization include Serialization # ... end end

Slide 41

Slide 41 text

Active Resource include ActiveModel::*

Slide 42

Slide 42 text

module ActiveResource class Base extend ActiveModel::Naming # Uses ActiveModel::Observing include Observing # Uses ActiveModel::Validations include Validations include ActiveModel::Conversion include ActiveModel::Serializers::JSON include ActiveModel::Serializers::Xml # ... end end

Slide 43

Slide 43 text

works how it

Slide 44

Slide 44 text

Validations

Slide 45

Slide 45 text

class Report < ActiveRecord::Base validates_presence_of :name end Active Record

Slide 46

Slide 46 text

report = Report.new puts report.valid? #=> false puts report.errors.full_messages #=> Name can't be blank Active Record

Slide 47

Slide 47 text

class Report include ActiveModel::Validations attr_accessor :name validates_presence_of :name end Active Model

Slide 48

Slide 48 text

class Report include ActiveModel::Validations attr_accessor :name validates_presence_of :name end Active Model include ActiveModel::Validations validates_presence_of :name

Slide 49

Slide 49 text

report = Report.new puts report.valid? #=> false puts report.errors.full_messages #=> Name can't be blank Active Model

Slide 50

Slide 50 text

Validator

Slide 51

Slide 51 text

class Report < ActiveRecord::Base validates_with ReportValidator end Active Record

Slide 52

Slide 52 text

class ReportValidator < ActiveModel::Validator def validate(report) if report.name.blank? report.errors.add :name, :blank end # More validations... end end Active Record

Slide 53

Slide 53 text

class ReportValidator < ActiveModel::Validator def validate(report) if report.name.blank? report.errors.add :name, :blank end # More validations... end end Active Record ReportValidator < ActiveModel::Validator def validate(report)

Slide 54

Slide 54 text

report = Report.new puts report.valid? #=> false puts report.errors.full_messages #=> Name can't be blank Active Record

Slide 55

Slide 55 text

class Report include ActiveModel::Validations validates_with ReportValidator attr_accessor :name end Active Model

Slide 56

Slide 56 text

class Report include ActiveModel::Validations validates_with ReportValidator attr_accessor :name end Active Model include ActiveModel::Validations validates_with ReportValidator

Slide 57

Slide 57 text

report = Report.new puts report.valid? #=> false puts report.errors.full_messages #=> Name can't be blank Active Model

Slide 58

Slide 58 text

Validations: Nova Sintaxe

Slide 59

Slide 59 text

class Report include ActiveModel::Validations attr_accessor :name # validates_presence_of :name validates :name, presence: true end Active Model

Slide 60

Slide 60 text

class Report include ActiveModel::Validations attr_accessor :name # validates_presence_of :name validates :name, presence: true end Active Model include ActiveModel::Validations validates :name, presence: true

Slide 61

Slide 61 text

Custom Validator

Slide 62

Slide 62 text

class Report include ActiveModel::Validations attr_accessor :no_name validates :no_name, absence: true end Active Model

Slide 63

Slide 63 text

class Report include ActiveModel::Validations attr_accessor :no_name validates :no_name, absence: true end include ActiveModel::Validations validates :no_name, absence: true Active Model

Slide 64

Slide 64 text

class AbsenceValidator < ActiveModel::EachValidator def validate_each(record, attribute, value) if value.present? record.errors.add attribute, :absence end end end Active Model

Slide 65

Slide 65 text

class AbsenceValidator < ActiveModel::EachValidator def validate_each(record, attribute, value) if value.present? record.errors.add attribute, :absence end end end AbsenceValidator Active Model

Slide 66

Slide 66 text

class AbsenceValidator < ActiveModel::EachValidator def validate_each(record, attribute, value) if value.present? record.errors.add attribute, :absence end end end AbsenceValidator Active Model AbsenceValidator < ActiveModel::EachValidator def validate_each(record, attribute, value)

Slide 67

Slide 67 text

Translation

Slide 68

Slide 68 text

# I18n: activerecord: attributes: report: name: 'Nome' puts Report.human_attribute_name('name') #=> "Nome" Active Record

Slide 69

Slide 69 text

# I18n: activemodel: attributes: report: name: 'Nome' Active Model

Slide 70

Slide 70 text

# I18n: activemodel: attributes: report: name: 'Nome' activemodel: Active Model

Slide 71

Slide 71 text

class Report extend ActiveModel::Translation end puts Report.human_attribute_name('name') #=> "Nome" Active Model

Slide 72

Slide 72 text

Validations + Translation

Slide 73

Slide 73 text

# I18n: activemodel: attributes: report: name: 'Nome' errors: messages: blank: 'deve ser preenchido' Active Model

Slide 74

Slide 74 text

report = Report.new puts report.valid? #=> false puts report.errors.full_messages #=> Nome deve ser preenchido Active Model

Slide 75

Slide 75 text

Callbacks

Slide 76

Slide 76 text

class Report < ActiveRecord::Base before_save { puts "it works before" } after_save { puts "it works after as well" } end Active Record

Slide 77

Slide 77 text

Report.new.save #=> it works before #=> ...saving... #=> it works after as well Active Record

Slide 78

Slide 78 text

class Report extend ActiveModel::Callbacks define_model_callbacks :save before_save { puts "it works before" } after_save { puts "it works after as well" } def save run_callbacks :save do puts "saving..." end end end Active Model

Slide 79

Slide 79 text

class Report extend ActiveModel::Callbacks define_model_callbacks :save before_save { puts "it works before" } after_save { puts "it works after as well" } def save run_callbacks :save do puts "saving..." end end end extend ActiveModel::Callbacks define_model_callbacks :save before_save { puts "it works before" } after_save { puts "it works after as well" } run_callbacks :save do puts "saving..." end Active Model

Slide 80

Slide 80 text

Report.new.save #=> it works before #=> ...saving... #=> it works after as well Active Model

Slide 81

Slide 81 text

Serialization

Slide 82

Slide 82 text

report = Report.new report.name = "Omglol" puts report.to_json #=> {"report":{"name":"Omglol"}} Active Record

Slide 83

Slide 83 text

class Report extend ActiveModel::Naming include ActiveModel::Serializers::JSON attr_accessor :name def attributes { name: name } end end Active Model

Slide 84

Slide 84 text

class Report extend ActiveModel::Naming include ActiveModel::Serializers::JSON attr_accessor :name def attributes { name: name } end end Active Model include ActiveModel::Serializers::JSON def attributes { name: name } end

Slide 85

Slide 85 text

report = Report.new report.name = "Omglol" puts report.to_json #=> {"report":{"name":"Omglol"}} Active Model

Slide 86

Slide 86 text

report = Report.new report.name = "Omglol" puts report.to_xml #=> #=> #=> Omglol #=> Active Record

Slide 87

Slide 87 text

class Report extend ActiveModel::Naming include ActiveModel::Serializers::Xml attr_accessor :name def attributes { name: name } end end Active Model

Slide 88

Slide 88 text

class Report extend ActiveModel::Naming include ActiveModel::Serializers::Xml attr_accessor :name def attributes { name: name } end end include ActiveModel::Serializers::Xml def attributes { name: name } end Active Model

Slide 89

Slide 89 text

report = Report.new report.name = "Omglol" puts report.to_xml #=> #=> #=> Omglol #=> Active Model

Slide 90

Slide 90 text

Attribute Methods

Slide 91

Slide 91 text

report = Report.new puts report.name? #=> false report.name = "Omglol" puts report.name? #=> true Active Record

Slide 92

Slide 92 text

report = Report.new puts report.name? #=> false report.name = "Omglol" puts report.name? #=> true report.name? #=> false report.name = "Omglol" report.name? #=> true Active Record

Slide 93

Slide 93 text

class Report include ActiveModel::AttributeMethods attribute_method_suffix '?' define_attribute_methods [:name] attr_accessor :name private def attribute?(attr) send(attr).present? end end Active Model

Slide 94

Slide 94 text

class Report include ActiveModel::AttributeMethods attribute_method_suffix '?' define_attribute_methods [:name] attr_accessor :name private def attribute?(attr) send(attr).present? end end include ActiveModel::AttributeMethods attribute_method_suffix '?' define_attribute_methods [:name] def attribute?(attr) send(attr).present? end Active Model

Slide 95

Slide 95 text

report = Report.new puts report.name? #=> false report.name = "Omglol" puts report.name? #=> true Active Model

Slide 96

Slide 96 text

report = Report.new puts report.name? #=> false report.name = "Omglol" puts report.name? #=> true report.name? #=> false report.name = "Omglol" report.name? #=> true Active Model

Slide 97

Slide 97 text

class Report include ActiveModel::AttributeMethods attribute_method_prefix 'clear_' define_attribute_methods [:name] attr_accessor :name private def clear_attribute(attr) send "#{attr}=", nil end end Active Model

Slide 98

Slide 98 text

class Report include ActiveModel::AttributeMethods attribute_method_prefix 'clear_' define_attribute_methods [:name] attr_accessor :name private def clear_attribute(attr) send "#{attr}=", nil end end Active Model include ActiveModel::AttributeMethods attribute_method_prefix 'clear_' define_attribute_methods [:name] def clear_attribute(attr) send "#{attr}=", nil end

Slide 99

Slide 99 text

report.name = "Omglol" puts report.name? #=> true report.clear_name puts report.name? #=> false Active Model

Slide 100

Slide 100 text

report.name = "Omglol" puts report.name? #=> true report.clear_name puts report.name? #=> false report.name? #=> true report.clear_name report.name? #=> false Active Model

Slide 101

Slide 101 text

DRY !

Slide 102

Slide 102 text

Active Model <3 <3 <3

Slide 103

Slide 103 text

isso... Enquanto

Slide 104

Slide 104 text

2.3.OMG Rails:

Slide 105

Slide 105 text

Invitation Feature:

Slide 106

Slide 106 text

class Invitation attr_accessor :contacts, :message end

Slide 107

Slide 107 text

<% form_for @invitation do |f| %> ... <% end %>

Slide 108

Slide 108 text

No content

Slide 109

Slide 109 text

WTF!?!

Slide 110

Slide 110 text

...

Slide 111

Slide 111 text

... action="/invitations/%23%3CInvitation: 0x1060c2b08%3E" What?

Slide 112

Slide 112 text

... class="edit_invitation" edit? LOL

Slide 113

Slide 113 text

... id="edit_invitation_2198214020" troll number

Slide 114

Slide 114 text

class Invitation attr_accessor :contacts, :message def new_record? true end def id nil end end

Slide 115

Slide 115 text

class Invitation attr_accessor :contacts, :message def new_record? true end def id nil end end def new_record? true end def id nil end

Slide 116

Slide 116 text

... there we go!

Slide 117

Slide 117 text

nisso? como chegar

Slide 118

Slide 118 text

Source diving!

Slide 119

Slide 119 text

Rails 2.3

Slide 120

Slide 120 text

Action Pack Active Record

Slide 121

Slide 121 text

Active Record? Blargh!?!!

Slide 122

Slide 122 text

NoSQL FTW!!

Slide 123

Slide 123 text

Action Pack Mongoid

Slide 124

Slide 124 text

monkey Patch

Slide 125

Slide 125 text

Outro objeto em um form?

Slide 126

Slide 126 text

monkey Patch

Slide 127

Slide 127 text

class Invitation attr_accessor :contacts, :message def new_record? true end def id nil end end def new_record? true end def id nil end

Slide 128

Slide 128 text

! API

Slide 129

Slide 129 text

Frágil

Slide 130

Slide 130 text

Rails 3

Slide 131

Slide 131 text

Rails 3 Rewrite Everything!

Slide 132

Slide 132 text

Active Model

Slide 133

Slide 133 text

Action Pack Active Model

Slide 134

Slide 134 text

Active Model Active Record Action Pack

Slide 135

Slide 135 text

Active Model Mongoid Action Pack

Slide 136

Slide 136 text

Outro objeto em um form?

Slide 137

Slide 137 text

Active Model OmgLol Action Pack

Slide 138

Slide 138 text

works how it

Slide 139

Slide 139 text

form_for @report do |f| f.label :name f.text_field :name f.submit end

Slide 140

Slide 140 text

Nome

Slide 141

Slide 141 text

Nome como?

Slide 142

Slide 142 text

Nome como?

Slide 143

Slide 143 text

Nome como?

Slide 144

Slide 144 text

Nome Nome como?

Slide 145

Slide 145 text

Nome Nome como?

Slide 146

Slide 146 text

Nome Nome como?

Slide 147

Slide 147 text

Nome como?

Slide 148

Slide 148 text

Nome como?

Slide 149

Slide 149 text

Nome como?

Slide 150

Slide 150 text

Nome como?

Slide 151

Slide 151 text

Nome como?

Slide 152

Slide 152 text

API Active Model

Slide 153

Slide 153 text

ActiveModel ::Lint::Tests

Slide 154

Slide 154 text

module ActiveModel::Lint::Tests def test_to_key; end def test_to_param; end def test_to_partial_path; end def test_valid?; end def test_persisted?; end def test_model_naming; end def test_errors_aref; end def test_errors_full_messages; end end

Slide 155

Slide 155 text

module ActiveModel::Lint::Tests def test_to_key; end def test_to_param; end def test_to_partial_path; end def test_valid?; end def test_persisted?; end def test_model_naming; end def test_errors_aref; end def test_errors_full_messages; end end to_key to_param to_partial_path valid? persisted? model_naming errors_aref errors_full_messages

Slide 156

Slide 156 text

module ActiveModel::Lint::Tests def test_to_key; end def test_to_param; end def test_to_partial_path; end def test_valid?; end def test_persisted?; end def test_model_naming; end def test_errors_aref; end def test_errors_full_messages; end end to_key to_param to_partial_path valid? persisted? model_naming errors_aref errors_full_messages Naming

Slide 157

Slide 157 text

class Report extend ActiveModel::Naming end

Slide 158

Slide 158 text

puts Report.model_name #=> "Report" puts Report.model_name.singular #=> report puts Report.model_name.plural #=> reports puts Report.model_name.param_key #=> report

Slide 159

Slide 159 text

puts Report.model_name #=> "Report" puts Report.model_name.singular #=> report puts Report.model_name.plural #=> reports puts Report.model_name.param_key #=> report model_name "Report" model_name.singular report model_name.plural reports model_name.param_key report

Slide 160

Slide 160 text

module ActiveModel::Lint::Tests def test_to_key; end def test_to_param; end def test_to_partial_path; end def test_valid?; end def test_persisted?; end def test_model_naming; end def test_errors_aref; end def test_errors_full_messages; end end to_key to_param to_partial_path valid? persisted? model_naming errors_aref errors_full_messages Conversion

Slide 161

Slide 161 text

module ActiveModel::Lint::Tests def test_to_key; end def test_to_param; end def test_to_partial_path; end def test_valid?; end def test_persisted?; end def test_model_naming; end def test_errors_aref; end def test_errors_full_messages; end end to_key to_param to_partial_path valid? persisted? model_naming errors_aref errors_full_messages Implementar

Slide 162

Slide 162 text

class Report include ActiveModel::Conversion attr_accessor :id def persisted? id.present? end end

Slide 163

Slide 163 text

report = Report.new report.id = 1 puts report.persisted? #=> true puts report.to_key #=> [1] puts report.to_param #=> '1'

Slide 164

Slide 164 text

report = Report.new report.id = 1 puts report.persisted? #=> true puts report.to_key #=> [1] puts report.to_param #=> '1' report.persisted? #=> true report.to_key #=> [1] report.to_param #=> '1'

Slide 165

Slide 165 text

module ActiveModel::Lint::Tests def test_to_key; end def test_to_param; end def test_to_partial_path; end def test_valid?; end def test_persisted?; end def test_model_naming; end def test_errors_aref; end def test_errors_full_messages; end end to_key to_param to_partial_path valid? persisted? model_naming errors_aref errors_full_messages Validations

Slide 166

Slide 166 text

require 'minitest/autorun' class OmglolTest < MiniTest::Unit::TestCase include ActiveModel::Lint::Tests def setup @model = Omglol.new end end

Slide 167

Slide 167 text

require 'minitest/autorun' class OmglolTest < MiniTest::Unit::TestCase include ActiveModel::Lint::Tests def setup @model = Omglol.new end end include ActiveModel::Lint::Tests def setup @model = Omglol.new end

Slide 168

Slide 168 text

require 'active_model' class Omglol extend ActiveModel::Naming include ActiveModel::Conversion include ActiveModel::Validations def persisted?; false; end end

Slide 169

Slide 169 text

require 'active_model' class Omglol extend ActiveModel::Naming include ActiveModel::Conversion include ActiveModel::Validations def persisted?; false; end end extend ActiveModel::Naming include ActiveModel::Conversion include ActiveModel::Validations def persisted?; false; end

Slide 170

Slide 170 text

$ ruby activemodel_test.rb Run options: --seed 9998 # Running tests: ........ Finished tests in 0.029155s, 274.3955 tests/s, 1303.3785 assertions/s. 8 tests, 38 assertions, 0 failures, 0 errors, 0 skips

Slide 171

Slide 171 text

$ ruby activemodel_test.rb Run options: --seed 9998 # Running tests: ........ Finished tests in 0.029155s, 274.3955 tests/s, 1303.3785 assertions/s. 8 tests, 38 assertions, 0 failures, 0 errors, 0 skips

Slide 172

Slide 172 text

Action Pack?

Slide 173

Slide 173 text

form_for @report

Slide 174

Slide 174 text

form_for @report do |f| f.label :name f.text_field :name f.submit end

Slide 175

Slide 175 text

new edit

Slide 176

Slide 176 text

url_for @report

Slide 177

Slide 177 text

url_for @report @report.persisted?

Slide 178

Slide 178 text

url_for @report @report.persisted? @report.to_param

Slide 179

Slide 179 text

url_for @report /reports /reports/1

Slide 180

Slide 180 text

dom_class @report

Slide 181

Slide 181 text

dom_class @report @report.class. model_name.param_key

Slide 182

Slide 182 text

dom_class @report @report.class. model_name.param_key “report”

Slide 183

Slide 183 text

dom_class @report, :new

Slide 184

Slide 184 text

dom_class @report, :new “new_report”

Slide 185

Slide 185 text

dom_id @report

Slide 186

Slide 186 text

dom_id @report dom_class @report

Slide 187

Slide 187 text

dom_id @report dom_class @report new_report / edit_report

Slide 188

Slide 188 text

dom_id @report

Slide 189

Slide 189 text

dom_id @report @report.to_key

Slide 190

Slide 190 text

dom_id @report @report.to_key edit_report_1

Slide 191

Slide 191 text

f.label :name

Slide 192

Slide 192 text

f.label :name model_name.param_key

Slide 193

Slide 193 text

f.label :name model_name.param_key “report_name”

Slide 194

Slide 194 text

f.label :name

Slide 195

Slide 195 text

f.label :name @report.class. human_attribute_name

Slide 196

Slide 196 text

f.label :name @report.class. human_attribute_name “Nome”

Slide 197

Slide 197 text

f.label :name Nome

Slide 198

Slide 198 text

f.text_field :name

Slide 199

Slide 199 text

f.text_field :name model_name.param_key

Slide 200

Slide 200 text

f.text_field :name model_name.param_key “report_name”

Slide 201

Slide 201 text

f.text_field :name model_name.param_key “report_name” “report[name]”

Slide 202

Slide 202 text

f.text_field :name

Slide 203

Slide 203 text

f.submit

Slide 204

Slide 204 text

f.submit @report.persisted?

Slide 205

Slide 205 text

f.submit @report.persisted? “Criar” ou “Atualizar”

Slide 206

Slide 206 text

f.submit

Slide 207

Slide 207 text

f.submit model_name.human

Slide 208

Slide 208 text

f.submit model_name.human “Relatório”

Slide 209

Slide 209 text

f.submit

Slide 210

Slide 210 text

form_for @report

Slide 211

Slide 211 text

form_for @report url_for dom_id dom_class

Slide 212

Slide 212 text

form_for @report

Slide 213

Slide 213 text

form_for @report model_name persisted? to_key

Slide 214

Slide 214 text

link_to “...”, @report

Slide 215

Slide 215 text

link_to “...”, @report url_for @report

Slide 216

Slide 216 text

div_for @report

Slide 217

Slide 217 text

div_for @report dom_id @report

Slide 218

Slide 218 text

div_for @report dom_id @report dom_class @report

Slide 219

Slide 219 text

render @report render @reports

Slide 220

Slide 220 text

render @report

Slide 221

Slide 221 text

render @report app/views/ reports/_report.html.erb

Slide 222

Slide 222 text

render @report

Slide 223

Slide 223 text

render @report @report.to_partial_path

Slide 224

Slide 224 text

render @report @report.to_partial_path reports/_report

Slide 225

Slide 225 text

respond_to :html, :json respond_with @report

Slide 226

Slide 226 text

respond_to :html, :json

Slide 227

Slide 227 text

respond_to :html, :json html? json?

Slide 228

Slide 228 text

respond_with @report

Slide 229

Slide 229 text

respond_with @report success? failure?

Slide 230

Slide 230 text

respond_with @report

Slide 231

Slide 231 text

respond_with @report @report.errors.empty?

Slide 232

Slide 232 text

module ActiveModel::Lint::Tests def test_to_key; end def test_to_param; end def test_to_partial_path; end def test_valid?; end def test_persisted?; end def test_model_naming; end def test_errors_aref; end def test_errors_full_messages; end end to_key to_param to_partial_path valid? persisted? model_naming errors_aref errors_full_messages

Slide 233

Slide 233 text

Validations?

Slide 234

Slide 234 text

module ActiveModel::Lint::Tests def test_to_key; end def test_to_param; end def test_to_partial_path; end def test_valid?; end def test_persisted?; end def test_model_naming; end def test_errors_aref; end def test_errors_full_messages; end end to_key to_param to_partial_path valid? persisted? model_naming errors_aref errors_full_messages Validations?

Slide 235

Slide 235 text

Rails 4 SPOILER

Slide 236

Slide 236 text

module ActiveModel::Lint::Tests def test_to_key; end def test_to_param; end def test_to_partial_path; end def test_valid?; end def test_persisted?; end def test_model_naming; end def test_errors_aref; end def test_errors_full_messages; end end RAILS 4 to_key to_param to_partial_path valid? persisted? model_naming errors_aref errors_full_messages

Slide 237

Slide 237 text

require 'minitest/autorun' class OmglolTest < MiniTest::Unit::TestCase include ActiveModel::Lint::Tests def setup @model = Omglol.new end end RAILS 4

Slide 238

Slide 238 text

require 'minitest/autorun' class OmglolTest < MiniTest::Unit::TestCase include ActiveModel::Lint::Tests def setup @model = Omglol.new end end RAILS 4 include ActiveModel::Lint::Tests def setup @model = Omglol.new end

Slide 239

Slide 239 text

require 'active_model' class Omglol extend ActiveModel::Naming include ActiveModel::Conversion def persisted?; false; end def errors; Hash.new([]); end end RAILS 4

Slide 240

Slide 240 text

require 'active_model' class Omglol extend ActiveModel::Naming include ActiveModel::Conversion def persisted?; false; end def errors; Hash.new([]); end end RAILS 4 def errors; Hash.new([]); end

Slide 241

Slide 241 text

require 'active_model' class Omglol extend ActiveModel::Naming include ActiveModel::Conversion def persisted?; false; end def errors; Hash.new([]); end end RAILS 4 extend ActiveModel::Naming include ActiveModel::Conversion def persisted?; false; end def errors; Hash.new([]); end def errors; Hash.new([]); end

Slide 242

Slide 242 text

$ ruby activemodel_master_test.rb Run options: --seed 10850 # Running tests: ...... Finished tests in 0.002590s, 2316.6023 tests/s, 11583.0116 assertions/s. 6 tests, 30 assertions, 0 failures, 0 errors, 0 skip

Slide 243

Slide 243 text

$ ruby activemodel_master_test.rb Run options: --seed 10850 # Running tests: ...... Finished tests in 0.002590s, 2316.6023 tests/s, 11583.0116 assertions/s. 6 tests, 30 assertions, 0 failures, 0 errors, 0 skip

Slide 244

Slide 244 text

API !

Slide 245

Slide 245 text

Active Model <3 <3 <3

Slide 246

Slide 246 text

Review

Slide 247

Slide 247 text

DRY Active Model

Slide 248

Slide 248 text

API Active Model

Slide 249

Slide 249 text

Bônus Track!

Slide 250

Slide 250 text

Rails 4 SPOILER

Slide 251

Slide 251 text

require 'active_model' class Omglol extend ActiveModel::Naming include ActiveModel::Conversion def persisted?; false; end def errors; Hash.new([]); end end RAILS 4

Slide 252

Slide 252 text

require 'active_model' class Omglol extend ActiveModel::Naming include ActiveModel::Conversion def persisted?; false; end def errors; Hash.new([]); end end RAILS 4 extend ActiveModel::Naming include ActiveModel::Conversion def persisted?; false; end def errors; Hash.new([]); end

Slide 253

Slide 253 text

ActiveModel ::Model

Slide 254

Slide 254 text

module Model def self.included(base) #:nodoc: base.class_eval do extend ActiveModel::Naming extend ActiveModel::Translation include ActiveModel::Validations include ActiveModel::Conversion end end def initialize(params={}) params.each do |attr, value| self.public_send("#{attr}=", value) end if params end def persisted? false end end RAILS 4

Slide 255

Slide 255 text

module Model def self.included(base) #:nodoc: base.class_eval do extend ActiveModel::Naming extend ActiveModel::Translation include ActiveModel::Validations include ActiveModel::Conversion end end def initialize(params={}) params.each do |attr, value| self.public_send("#{attr}=", value) end if params end def persisted? false end end RAILS 4 extend ActiveModel::Naming extend ActiveModel::Translation include ActiveModel::Validations include ActiveModel::Conversion def persisted? false end

Slide 256

Slide 256 text

require 'active_model' class Omglol include ActiveModel::Model end RAILS 4

Slide 257

Slide 257 text

require 'active_model' class Omglol include ActiveModel::Model end RAILS 4 include ActiveModel::Model

Slide 258

Slide 258 text

form_for @omglol

Slide 259

Slide 259 text

render @omglol

Slide 260

Slide 260 text

respond_with @omglol

Slide 261

Slide 261 text

Active Model <3 <3 <3

Slide 262

Slide 262 text

No content

Slide 263

Slide 263 text

Active Model Attribute Methods Callbacks Dirty Mass Assignment Secure Password Observing Serialization Validations Validator Model Conversion Naming Translation Lint

Slide 264

Slide 264 text

plataformatec/ mail_form

Slide 265

Slide 265 text

http://pragprog.com/book/jvrails/crafting-rails-applications

Slide 266

Slide 266 text

WITH GREAT MOUSTACHE COMES GREAT RESPONSIBILITY

Slide 267

Slide 267 text

Estamos contratando! plataformatec.com.br

Slide 268

Slide 268 text

No content

Slide 269

Slide 269 text

APLICAÇÕES MELHORES ACTIVE MODEL @cantoniodasilva Obrigado!