Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 129 lines (96 sloc) 3.304 kb
b6ee191 @clayallsopp testing the read me markdown
authored
1 # RemoteModel
2
3
4 JSON API <-> NSObject in one line. Powered by RubyMotion and [BubbleWrap](https://github.com/mattetti/BubbleWrap/).
5
6 ## Installation
7
8 Add the git repos as submodules in ./vendor:
9
9491079 @clayallsopp more readme cleanup
authored
10 ```shell
11 git submodule add git://github.com/mattetti/BubbleWrap.git ./vendor/BubbleWrap
12 git submodule add git://github.com:clayallsopp/remote_model.git ./vendor/remote_model
13 ```
b6ee191 @clayallsopp testing the read me markdown
authored
14
15 Then add the lib paths to your ./Rakefile:
16
17 ```ruby
18 Motion::Project::App.setup do |app|
19 ...
c673fbc @clayallsopp clean up the readme
authored
20 app.files = Dir.glob(File.join(app.project_dir, 'vendor/BubbleWrap/lib/**/*.rb'))
21 + Dir.glob(File.join(app.project_dir, 'vendor/remote_model/lib/**/*.rb'))
22 + app.files
b6ee191 @clayallsopp testing the read me markdown
authored
23 ...
24 end
25 ```
26
27 Add an initialization file somewhere, like ./app/initializers/remote_model.rb. This is where we put the API specifications:
28
29 ```ruby
30 module RemoteModule
31 class RemoteModel
32 # The default URL for our requests.
33 # Overrideable per model subclass
34 self.root_url = "http://localhost:5000/"
35
36 # Options attached to every request
37 # Appendable per model subclass
38 self.default_url_options = {
39 :headers => {
40 "x-api-token" => "some_token",
41 "Accept" => "application/json"
42 }
43 }
44 end
45 end
46 ```
47
48 ## Example
49
f331547 @clayallsopp more concise readme
authored
50 Let's say we have some User and Question objects retrievable via our API. We can do fun stuff like:
51
52 ```ruby
53 user = User.find(1) do |user|
54 # async
55 Question.find_all(user_id: user.id) do |questions|
56 # async
57 puts questions
58 end
59 end
60
61 # Later...
6d41a3d @clayallsopp updated readme
authored
62 => [#<Question @user=#<User>,
63 #<Question @user=#<User>]
f331547 @clayallsopp more concise readme
authored
64 ```
65
66 Here's what our files look like:
b6ee191 @clayallsopp testing the read me markdown
authored
67
68 #### ./app/models/user
69 ```ruby
70 class User < RemoteModule::RemoteModel
c673fbc @clayallsopp clean up the readme
authored
71 attr_accessor :id
b6ee191 @clayallsopp testing the read me markdown
authored
72
73 has_many :questions
74
75 collection_url "users"
76 member_url "users/:id"
77 end
78 ```
79
80 #### ./app/models/question.rb
81 ```ruby
82 class Question < RemoteModule::RemoteModel
83 attr_accessor :id, :question, :is_active
84
85 belongs_to :user
86
87 collection_url "users/:user_id/questions"
88 member_url "users/:user_id/questions/:id"
89
90 custom_urls :active_url => member_url + "/make_active"
91
92 def user_id
93 user && user.id
94 end
95
c673fbc @clayallsopp clean up the readme
authored
96 def make_active(active)
b6ee191 @clayallsopp testing the read me markdown
authored
97 post(self.active_url, payload: {active: active}) do |response, json|
98 self.is_active = json[:question][:is_active]
c673fbc @clayallsopp clean up the readme
authored
99 if block_given?
100 yield self
b6ee191 @clayallsopp testing the read me markdown
authored
101 end
102 end
103 end
104 end
6d41a3d @clayallsopp updated readme
authored
105 ```
106
107 ## How?
108
109 RemoteModel is designed for JSON apis which return structures with "nice" properties.
110
111 When you make a request with a RemoteModel (self.get/put/post/delete), the result is always parsed as JSON. The ActiveRecord-esque methods take this JSON and create objects out of it. It's clever and creates the proper associations (belongs_to/has_one/has_many) within the objects, as defined in the models.
112
113 #### FormatableString
114
115 The AR methods also use the member/collection defined URLs to make requests. These URLs are a string which you can use :symbols to input dynamic values. These strings can be formatted using a hash and/or taking an object (it will look to see if the object responds to these symbols and call the method if applicable):
116
117 ```ruby
118 >> s = RemoteModule::FormatableString.new("url/:param")
119 => "url/:param"
120 >> s.format({param: 6})
121 => "url/6"
122 ```
123
124 RemoteModels can define custom urls and call those as methods (see question.rb above).
125
126 ## Todo
127
128 - More tests
129 - CoreData integration
Something went wrong with that request. Please try again.