liaison 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/ChangeLog ADDED
@@ -0,0 +1,9 @@
1
+ 2011-09-20 Mike Burns <mburns@thoughtbot.com>
2
+
3
+ * presenter.rb, presenter_spec.rb:
4
+ Include the Enumerable module to the Presenter class, with a test.
5
+
6
+ * NEWS, ChangeLog:
7
+ Add an overview NEWS file and a more detailed ChangeLog file.
8
+
9
+ * version.rb: Bump version to 0.0.2.
data/NEWS ADDED
@@ -0,0 +1,4 @@
1
+ New in 0.0.2:
2
+
3
+ * The Presenter class now includes the Enumerable class. This means you can
4
+ use #map, #reject, #sort, and so on, on the Presenter data object.
data/README.md CHANGED
@@ -3,6 +3,28 @@ Liaison
3
3
 
4
4
  A Rails presenter class.
5
5
 
6
+ How to Use Liaison
7
+ ------------------
8
+
9
+ Add this to your `Gemfile`:
10
+
11
+ gem 'liaison'
12
+
13
+ Then run the bundler installer:
14
+
15
+ bundle
16
+
17
+ You instantiate `Presenter` classes in your controllers, setting them as instance variables so they can be passed to the views. The `Presenter` class takes the model name as a string (`sign_up`, for example) then a hash of options. Currently supported options are `:fields`, a list of attributes on the presenter (`[:email, :password]`); and `:validator`, a class that knows how to validate the data (`SignUpValidator`).
18
+
19
+ An instance of the `Presenter` object is Hash-like: it implements the `Enumerable` module, which means it has an `#each` method among many others; it also has a `#[]` method, which you can use to access values just like with the CGI `params` hash.
20
+
21
+ The business logic classes (`SignUp` in the below example) live under `app/models` and are tested as normal, except instead of requiring `spec_helper` they can likely require just `rspec`.
22
+
23
+ Validator classes (`SignUpValidator` in the below example) live under `lib` and must either descend from `ActiveModel::Validator` or implement the same interface (`.kind`, `#kind`, `#validate` that takes a record, and a constructor that takes a hash of options). They are also unit tested like normal and can likely get away with just requiring `rspec` instead of `spec_helper`. Sadly, in order to hook into the `ActiveModel::Validations` framework, you must pass the validator class itself instead of an object (`SignUpValidator` vs `SignUpValidator.new`).
24
+
25
+ Turorial and Thought Process
26
+ ----------------------------
27
+
6
28
  A major idea of [the presenter pattern](http://blog.jayfields.com/2007/03/rails-presenter-pattern.html) is to break off the business logic from the view object, letting the view logic be a dumb instance that knows how to get, set, and validate values. The business logic can then query the presenter object for the values as needed.
7
29
 
8
30
  Look, here's an example business object:
@@ -76,11 +98,6 @@ The `presenter` method in the above example produces a new `Presenter` instance.
76
98
 
77
99
  You, the author of the business logic class, are in charge of checking in on these validations and errors. For example, before saving any objects you should check `Presenter#valid?`. And after you've saved something to the database you should add any errors onto the presenter using `Presenter#add_errors`.
78
100
 
79
- Getting Data
80
- ----------
81
-
82
- An instance of the `Presenter` object is Hash-like: it implements the `Enumerable` module, which means it has an `#each` method among many others; it also has a `#[]` method, which you can use to access values just like with the CGI `params` hash.
83
-
84
101
  Testing
85
102
  -------
86
103
 
@@ -4,6 +4,7 @@ class Presenter
4
4
  extend ActiveModel::Naming
5
5
  include ActiveModel::Conversion
6
6
  include ActiveModel::Validations
7
+ include Enumerable
7
8
 
8
9
  validate :instance_validations
9
10
 
@@ -24,25 +25,22 @@ class Presenter
24
25
  self.class.send(:attr_accessor,*@fields) unless @fields.nil? || @fields.empty?
25
26
  end
26
27
 
27
- def instance_validations
28
- validates_with(@validator, :attributes => @fields) if @validator
29
- end
30
-
28
+ # This only exists for ActiveModel::Naming
31
29
  def self.model_name # :nodoc:
32
- ActiveModel::Name.new(Class.new do
33
- attr_reader :name
34
- def initialize(n)
35
- @name = n
36
- end
37
- end.new(@@model_name))
30
+ model_namer = Struct.new("ModelNamer", :name).new(@@model_name)
31
+ ActiveModel::Name.new(model_namer)
38
32
  end
39
33
 
34
+ # This only exists for ActiveModel::Constructs
40
35
  def persisted? # :nodoc:
41
36
  false
42
37
  end
43
38
 
44
39
  # Set the params from the form using this.
45
40
  #
41
+ # For example, if you have a presenter in the @sign_up_presenter variable,
42
+ # you can update the values in it using this method:
43
+ #
46
44
  # @sign_up_presenter.with_params(params[:sign_up])
47
45
  def with_params(params = {})
48
46
  params.each {|k,v| self.send("#{k}=", v)}
@@ -76,8 +74,8 @@ class Presenter
76
74
  to_hash[key]
77
75
  end
78
76
 
79
- # This is an instance of Enumerable, which means you can iterate over the
80
- # keys and values as set by the form.
77
+ # Presenter objects are instances of Enumerable, which means you can iterate
78
+ # over the keys and values as set by the form.
81
79
  #
82
80
  # @sign_up_presenter.each {|k,v| puts "the form set #{k} to #{v}" }
83
81
  def each(&block)
@@ -92,4 +90,8 @@ class Presenter
92
90
  acc
93
91
  end
94
92
  end
93
+
94
+ def instance_validations
95
+ validates_with(@validator, :attributes => @fields) if @validator
96
+ end
95
97
  end
@@ -1,3 +1,3 @@
1
1
  module Liaison
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -96,4 +96,8 @@ describe Presenter, "enumerations" do
96
96
  subject[:a].should == 'hello'
97
97
  subject[:b].should == 'goodbye'
98
98
  end
99
+
100
+ it "has at least #reject" do
101
+ subject.reject {|k,v| k == :a}.should == [[:b, 'goodbye']]
102
+ end
99
103
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: liaison
3
3
  version: !ruby/object:Gem::Version
4
- hash: 29
4
+ hash: 27
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 1
10
- version: 0.0.1
9
+ - 2
10
+ version: 0.0.2
11
11
  platform: ruby
12
12
  authors:
13
13
  - Mike Burns
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-09-10 00:00:00 Z
18
+ date: 2011-09-20 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: activemodel
@@ -70,8 +70,10 @@ extra_rdoc_files: []
70
70
 
71
71
  files:
72
72
  - .gitignore
73
+ - ChangeLog
73
74
  - Gemfile
74
75
  - LICENSE
76
+ - NEWS
75
77
  - README.md
76
78
  - Rakefile
77
79
  - liaison.gemspec