motion-resource 0.1.2 → 0.1.3

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.
@@ -17,7 +17,13 @@ module MotionResource
17
17
  end
18
18
  end
19
19
 
20
- def has_many(name, params = lambda { |o| Hash.new })
20
+ def has_many(name, options = {})
21
+ default_options = {
22
+ :params => lambda { |o| Hash.new },
23
+ :class_name => name.to_s.classify
24
+ }
25
+ options = default_options.merge(options)
26
+
21
27
  backwards_association = self.name.underscore
22
28
 
23
29
  define_method name do |&block|
@@ -29,8 +35,10 @@ module MotionResource
29
35
  MotionResource::Base.request_block_call(block, cached, cached_response)
30
36
  return
31
37
  end
38
+
39
+ klass = options[:class_name].constantize
32
40
 
33
- Object.const_get(name.to_s.classify).find_all(params.call(self)) do |results, response|
41
+ klass.find_all(options[:params].call(self)) do |results, response|
34
42
  if results && results.first && results.first.respond_to?("#{backwards_association}=")
35
43
  results.each do |result|
36
44
  result.send("#{backwards_association}=", self)
@@ -44,7 +52,8 @@ module MotionResource
44
52
  end
45
53
 
46
54
  define_method "#{name}=" do |array|
47
- klass = Object.const_get(name.to_s.classify)
55
+ klass = options[:class_name].constantize
56
+
48
57
  instance_variable_set("@#{name}", [])
49
58
 
50
59
  array.each do |value|
@@ -2,6 +2,9 @@ module MotionResource
2
2
  class Base
3
3
  include MotionSupport::DescendantsTracker
4
4
 
5
+ class_attribute :primary_key
6
+ self.primary_key = :id
7
+
5
8
  attr_accessor :id
6
9
 
7
10
  def initialize(params = {})
@@ -16,7 +19,7 @@ module MotionResource
16
19
  class << self
17
20
  def instantiate(json)
18
21
  json = json.symbolize_keys
19
- raise ArgumentError, "No :id parameter given for #{self.name}.instantiate" unless json[:id]
22
+ raise ArgumentError, "No :#{primary_key} parameter given for #{self.name}.instantiate" unless json[primary_key]
20
23
 
21
24
  klass = if json[:type]
22
25
  begin
@@ -28,11 +31,11 @@ module MotionResource
28
31
  self
29
32
  end
30
33
 
31
- if result = klass.recall(json[:id])
34
+ if result = klass.recall(json[primary_key])
32
35
  result.update_attributes(json)
33
36
  else
34
37
  result = klass.new(json)
35
- klass.remember(result.id, result)
38
+ klass.remember(result.send(result.primary_key), result)
36
39
  end
37
40
  result.send(:instance_variable_set, "@new_record", false)
38
41
  result
@@ -2,11 +2,11 @@ module MotionResource
2
2
  class Base
3
3
  class << self
4
4
  def find(id, params = {}, &block)
5
- fetch_member(member_url.fill_url_params(params.merge(id: id)), &block)
5
+ fetch_member(member_url_or_default.fill_url_params(params.merge(id: id)), &block)
6
6
  end
7
7
 
8
8
  def find_all(params = {}, &block)
9
- fetch_collection(collection_url.fill_url_params(params), &block)
9
+ fetch_collection(collection_url_or_default.fill_url_params(params), &block)
10
10
  end
11
11
 
12
12
  def fetch_member(url, &block)
@@ -27,7 +27,7 @@ class String
27
27
  # fake a url so we avoid regex nastiness with URL's
28
28
  url = NSURL.URLWithString("http://blah.com/#{self}")
29
29
  # build our query string (needs encoding support!)
30
- query_string = params.map{|k,v| "#{k}=#{v}"}.join('&')
30
+ query_string = params.to_query
31
31
  if url.query.nil? || url.query.empty?
32
32
  # strip the beginning / and add the query
33
33
  self.replace "#{url.path[1..-1]}?#{query_string}"
@@ -16,14 +16,22 @@ module MotionResource
16
16
  end
17
17
  end
18
18
  end
19
+
20
+ def collection_url_or_default
21
+ collection_url || name.underscore.pluralize
22
+ end
23
+
24
+ def member_url_or_default
25
+ member_url || "#{name.underscore.pluralize}/:#{primary_key}"
26
+ end
19
27
  end
20
28
 
21
29
  def collection_url(params = {})
22
- self.class.collection_url.fill_url_params(params, self)
30
+ self.class.collection_url_or_default.fill_url_params(params, self)
23
31
  end
24
32
 
25
33
  def member_url(params = {})
26
- self.class.member_url.fill_url_params(params, self)
34
+ self.class.member_url_or_default.fill_url_params(params, self)
27
35
  end
28
36
  end
29
37
  end
@@ -1,3 +1,3 @@
1
1
  module MotionResource
2
- VERSION = "0.1.2"
2
+ VERSION = "0.1.3"
3
3
  end
data/spec/env.rb CHANGED
@@ -6,6 +6,7 @@ class Post < MotionResource::Base
6
6
  self.member_url = 'posts/:id'
7
7
 
8
8
  has_many :comments
9
+ has_many :parent_posts, :class_name => 'Post'
9
10
  end
10
11
 
11
12
  class Comment < MotionResource::Base
@@ -39,3 +40,8 @@ end
39
40
  class Rectangle < Shape
40
41
  attribute :size
41
42
  end
43
+
44
+ class Membership < MotionResource::Base
45
+ self.primary_key = :membership_id
46
+ attr_accessor :membership_id
47
+ end
@@ -20,6 +20,27 @@ describe "has_many" do
20
20
  post.comments.should == []
21
21
  end
22
22
 
23
+ describe "custom class name" do
24
+ extend WebStub::SpecHelpers
25
+
26
+ before do
27
+ stub_request(:get, "http://example.com/posts.json").to_return(json: [{ id: 1, text: 'Whats up?' }])
28
+ end
29
+
30
+ it "should fetch resources when called with a block" do
31
+ @post = Post.new
32
+ @post.parent_posts do |results|
33
+ @results = results
34
+ resume
35
+ end
36
+
37
+ wait_max 1.0 do
38
+ @results.size.should == 1
39
+ @results.first.text.should == 'Whats up?'
40
+ end
41
+ end
42
+ end
43
+
23
44
  describe "reader" do
24
45
  extend WebStub::SpecHelpers
25
46
 
@@ -1,6 +1,16 @@
1
1
  describe "base" do
2
- it "should define the id method" do
3
- Post.new.should.respond_to :id
2
+ describe "primary key" do
3
+ it "should have a default primary key" do
4
+ Post.primary_key.should == :id
5
+ end
6
+
7
+ it "should be overridable" do
8
+ Membership.primary_key.should == :membership_id
9
+ end
10
+
11
+ it "should define the id method" do
12
+ Post.new.should.respond_to :id
13
+ end
4
14
  end
5
15
 
6
16
  it "should set new_record to true when calling new" do
@@ -22,6 +32,11 @@ describe "base" do
22
32
  shape.should.is_a Rectangle
23
33
  end
24
34
 
35
+ it "should instantiate with non-standard primary key" do
36
+ membership = Membership.instantiate(:membership_id => 1)
37
+ membership.should.is_a Membership
38
+ end
39
+
25
40
  it "should instantiate base type if concrete type does not exist" do
26
41
  shape = Shape.instantiate(:id => 2, :type => 'FuzzyCircle')
27
42
  shape.should.is_a Shape
@@ -19,6 +19,18 @@ describe "urls" do
19
19
  MotionResource::Base.extension.should == '.json'
20
20
  end
21
21
 
22
+ it "should have a default collection URL" do
23
+ Rectangle.collection_url_or_default.should == "rectangles"
24
+ end
25
+
26
+ it "should have a default member URL" do
27
+ Rectangle.member_url_or_default.should == "rectangles/:id"
28
+ end
29
+
30
+ it "should have a default member URL with custom primary key" do
31
+ Membership.member_url_or_default.should == "memberships/:membership_id"
32
+ end
33
+
22
34
  it "should define custom url method" do
23
35
  comment = Comment.new
24
36
  comment.should.respond_to :by_user_url
@@ -43,10 +55,25 @@ describe "urls" do
43
55
  comment.collection_url.should == 'comments'
44
56
  end
45
57
 
58
+ it "should fall back to default URL in collection_url method" do
59
+ rectangle = Rectangle.new
60
+ rectangle.collection_url.should == 'rectangles'
61
+ end
62
+
46
63
  it "should define convenience member_url method" do
47
64
  comment = Comment.new
48
65
  comment.should.respond_to :member_url
49
66
  comment.member_url.should.is_a String
50
67
  comment.member_url(id: 10).should == 'comments/10'
51
68
  end
69
+
70
+ it "should fall back to default URL in collection_url method" do
71
+ rectangle = Rectangle.new
72
+ rectangle.member_url(:id => 10).should == 'rectangles/10'
73
+ end
74
+
75
+ it "should fall back to default URL in collection_url method with custom primary key" do
76
+ membership = Membership.new
77
+ membership.member_url(:membership_id => 10).should == 'memberships/10'
78
+ end
52
79
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: motion-resource
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-05-12 00:00:00.000000000 Z
12
+ date: 2013-05-23 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bubble-wrap
@@ -121,7 +121,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
121
121
  version: '0'
122
122
  segments:
123
123
  - 0
124
- hash: 4144364702470032416
124
+ hash: -3993476988303272926
125
125
  required_rubygems_version: !ruby/object:Gem::Requirement
126
126
  none: false
127
127
  requirements:
@@ -130,7 +130,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
130
130
  version: '0'
131
131
  segments:
132
132
  - 0
133
- hash: 4144364702470032416
133
+ hash: -3993476988303272926
134
134
  requirements: []
135
135
  rubyforge_project:
136
136
  rubygems_version: 1.8.25