ActiveResource探究一
本教程向大家展示使用ActiveResource创建简单的REST风格的API。包括两个嵌套得Model、认证和客户端。目的是快速地搭建一个可用的REST API。
步骤一:新建一个项目
rails ares-demo
使用rails 2.0.2版本,我想这与版本无关。
步骤二:安装两个好用的插件
Resource This插件会将默认rest风格的action加到controller上。并且支持多层资源嵌套...通过下面的命令安装:
script/plugin install http://jnewland.com/svn/public/ruby/rails/plugins/resource_this/
Restful Authentication众所周知是一个认证插件,通过下面的命令安装:
script/plugin install http://svn.techno-weenie.net/projects/plugins/restful_authentication/
步骤三:设置restful authentication
非常简单,使用生成器生成migrations还有其他一些东西,具体用法请搜索restful authentication的用法指导
./script/generate authenticated user sessions
步骤四:生成程序Model
接下来就是生成你的model了。我门做一个简单的,posts包括很多comments,posts和comments都属于user,命令如下:
./script/generate scaffold posts ./script/generate scaffold comments
下面修改migration文件,如下:
db/migrate/002_create_posts.rb
class CreatePosts < ActiveRecord::Migration def self.up create_table :posts do |t| t.column :content, :text t.column :user_id, :integer t.timestamps end end def self.down drop_table :posts end end
db/migrate/003_create_comments.rb
class CreateComments < ActiveRecord::Migration def self.up create_table :comments do |t| t.column :content, :text t.column :user_id, :integer t.column :post_id, :integer t.timestamps end end def self.down drop_table :comments end end
Next you'll need to add the relationships to your model classes. Add the following bit to the front of app/models/user.rb
下一步给这三个模型加上关联:
class User < ActiveRecord::Base # custom relationships has_many :posts has_many :comments
app/models/post.rb
class Post < ActiveRecord::Base belongs_to :user has_many :comments end
and app/models/comment.rb
class Comment < ActiveRecord::Base belongs_to :user belongs_to :post end
用下面命令生成数据库:
rake db:migrate
步骤五:装载测试数据
添加一些默认数据,执行命令script/console,如下:
>> u1 = User.new(:login => "test1", :email => "test1@foo.com", :password => "test1", :password_confirmation => "test1") => #<User id: nil, login: "test1", email: "test1@foo.com", crypted_password: nil, salt: nil, created_at: nil, updated_at: nil, remember_token: nil, remember_token_expires_at: nil> >> u1.save => true >> u2 = User.new(:login => "test2", :email => "test2@foo.com", :password => "test2", :password_confirmation => "test2") => #<User id: nil, login: "test2", email: "test2@foo.com", crypted_password: nil, salt: nil, created_at: nil, updated_at: nil, remember_token: nil, remember_token_expires_at: nil> >> u2.save => true >> p = Post.new(:user => u1, :content => "The first post") => #<Post id: nil, content: "The first post", user_id: 1, created_at: nil, updated_at: nil> >> p.save => true >> c = Comment.new(:user => u2, :post => p, :content => "first!") => #<Comment id: nil, content: "first!", user_id: 2, post_id: 1, created_at: nil, updated_at: nil> >> c.save => true >>
步骤六:resource_this!
接下来我们用插件resource_this!修改如下文件app/controllers/posts_controller.rb
class PostsController < ApplicationController resource_this end
app/controllers/comments_controller.rb
class CommentsController < ApplicationController resource_this :nested => [:post] end
And finally update config/routes.rb
ActionController::Routing::Routes.draw do |map| map.resources :posts do |post| post.resources :comments end map.resources :users map.resource :session end
就是这样,现在你可以关注你的API了!
步骤七:浏览
用命令script/server启动网站服务器,访问下面的链接
步骤八:开船
到目前为止,我们的service对所有人开放。我们将加入简单的认证,我们将对某些action加以控制:
修改app/controllers/application.rb
class ApplicationController < ActionController::Base include AuthenticatedSystem before_filter :login_required, :only => [:create,:edit,:new,:update,:destroy] helper :all # include all helpers, all the time # See ActionController::RequestForgeryProtection for details # Uncomment the :secret if you're not using the cookie session store protect_from_forgery # :secret => 'b845cf981afbfef06600e5d7f23e0fed' end
步骤九:客户端
我们可以通过curl或浏览器测试,但是ActiveResource真正的魅力是使用ruby对象测试。所以我们将创建一个简单的客户端api。在lib目录下建一个文件"ares_sample_client.rb",并加入以下代码:
require 'activeresource' module Sample module Client class API class Post < ActiveResource::Base self.site = "http://localhost:3000" end class Comment < ActiveResource::Base self.site = "http://localhost:3000" end end end end
现在我们可以同两国console来测试我们的成果了,确保server启动在3000端口,并且启动console:script/console
>> require 'ares_sample_client.rb' => ["Sample"] >> posts = Sample::Client::API::Post.find(:all) => [#<Sample::Client::API::Post:0xb710bec4 @attributes={"updated_at"=>Wed Jan 09 02:36:34 UTC 2008, "id"=>1, "content"=>"The first post", "user_id"=>1, "created_at"=>Wed Jan 09 02:36:34 UTC 2008}, @prefix_options={}>] >> >> p = Sample::Client::API::Post.create ActiveResource::UnauthorizedAccess: Failed with 401 Unauthorized from /usr/lib/ruby/gems/1.8/gems/activeresource-2.0.2/lib/active_resource/connection.rb:125:in `handle_response' from /usr/lib/ruby/gems/1.8/gems/activeresource-2.0.2/lib/active_resource/connection.rb:112:in `request' from /usr/lib/ruby/gems/1.8/gems/activeresource-2.0.2/lib/active_resource/connection.rb:101:in `post' from /usr/lib/ruby/gems/1.8/gems/activeresource-2.0.2/lib/active_resource/base.rb:803:in `create' from /usr/lib/ruby/gems/1.8/gems/activeresource-2.0.2/lib/active_resource/base.rb:636:in `save_without_validation' from /usr/lib/ruby/gems/1.8/gems/activeresource-2.0.2/lib/active_resource/validations.rb:262:in `save' from /usr/lib/ruby/gems/1.8/gems/activeresource-2.0.2/lib/active_resource/base.rb:339:in `create' from /usr/lib/ruby/gems/1.8/gems/activesupport-2.0.2/lib/active_support/core_ext/object/misc.rb:28:in `returning' from /usr/lib/ruby/gems/1.8/gems/activeresource-2.0.2/lib/active_resource/base.rb:339:in `create' from (irb):3 >>
我们的API成功了,认证系统也发挥作用了。我们没有通过认证,所有不能够创建post,那么现在我们就加入认证来测试一下:
module Sample module Client class API class Post < ActiveResource::Base self.site = "http://test1:test1@localhost:3000" end class Comment < ActiveResource::Base self.site = "http://test1:test1@localhost:3000" end end end end
需要注意的是,认证应用在整个类...这是的api使用相当容易,但是使多个用户使用变困难了,不管如何,我们的程序起作用了,我们再看看:
>> p = Sample::Client::API::Post.create(:content => "Should succeed", :user_id => 1) => #<Sample::Client::API::Post:0xb71b81d8 @attributes={"updated_at"=>Wed Jan 09 02:55:22 UTC 2008, "id"=>3, "content"=>"Should succeed", "user_id"=>1, "created_at"=>Wed Jan 09 02:55:22 UTC 2008}, @prefix_options={}> >> p.save => true >>
非常好!