liaison 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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