一个常见REST应用场景的困惑和探究
来源:互联网 发布:网络棋牌代理赚钱吗 编辑:程序博客网 时间:2024/06/05 09:47
下面是一个最常碰到的应用场景:
一个论坛应用(如: javaeye)。文章资源是一个嵌套关系: 栏目(board)-->分类(category)-->文章(topic),其routes.rb里的配置可能如下:
列出某分类下的所有主题的URL则是这样的:http://***/boards/2/categories/4/topics
但是我们有时可能需要列出某栏目下的所有主题。于是可能需要这样的URL: http://***/boards/2/topics
要实现这样的URL的需要修改一下routes,如下。
但这样方式有点问题:在构造URL时 topics_path(@board,@category)有效,但topics_path(@board)无效。
但是......,我们可能还要搜索附合一些关键字条件的文章,也许需要这样的URL: http://***/boards/2/topics?keyword="rails ruby"
或者象javaeye现在的处理方式用URL:http://***/borads/ajax_search?keyword="rails ruby"
------------------------------------------------------------------
又或许我们就抛弃嵌套方案,直接定义topics资源,如下
一个论坛应用(如: javaeye)。文章资源是一个嵌套关系: 栏目(board)-->分类(category)-->文章(topic),其routes.rb里的配置可能如下:
- map.resources :boards do |board|
- board.resources :categories do |category|
- category.resources :topics
- end
- end
map.resources :boards do |board| board.resources :categories do |category| category.resources :topics end end
列出某分类下的所有主题的URL则是这样的:http://***/boards/2/categories/4/topics
但是我们有时可能需要列出某栏目下的所有主题。于是可能需要这样的URL: http://***/boards/2/topics
要实现这样的URL的需要修改一下routes,如下。
- map.resources :boards do |board|
- <SPAN style="COLOR: red">board.resources :topics</SPAN>
- board.resources :categories do |category|
- category.resources :topics
- end
- end
map.resources :boards do |board| board.resources :topics board.resources :categories do |category| category.resources :topics end end
但这样方式有点问题:在构造URL时 topics_path(@board,@category)有效,但topics_path(@board)无效。
但是......,我们可能还要搜索附合一些关键字条件的文章,也许需要这样的URL: http://***/boards/2/topics?keyword="rails ruby"
或者象javaeye现在的处理方式用URL:http://***/borads/ajax_search?keyword="rails ruby"
------------------------------------------------------------------
又或许我们就抛弃嵌套方案,直接定义topics资源,如下
- map.resources :topics
map.resources :topics
以后删除和查看都很容易构造URL,只需要文章id就行了: http://***/topics/1
如果要查某栏目、某分类下的文章就在topics_controller里创建几个自定义action。
刚说没有可供参考的案例,突然想到了http://beast.caboo.se/,看看它是怎么实现的
它有这样的嵌套关系: forums--> topics -->posts (即 栏目-->帖子-->回复)
关于posts的routes如下。
- map.resources :forums, :has_many => [:posts] do |forum|
- forum.resources :topics, :name_prefix => nil do |topic|
- topic.resources :posts, :name_prefix => nil
- topic.resource :monitorship, :name_prefix => nil
- end
- end
- map.resources :posts, :name_prefix => 'all_', :collection => { :search => :get }
- map.with_options :controller => 'posts', :action => 'monitored' do |map|
- map.formatted_monitored_posts 'users/:user_id/monitored.:format'
- map.monitored_posts 'users/:user_id/monitored'
- end
map.resources :forums, :has_many => [:posts] do |forum| forum.resources :topics, :name_prefix => nil do |topic| topic.resources :posts, :name_prefix => nil topic.resource :monitorship, :name_prefix => nil end end map.resources :posts, :name_prefix => 'all_', :collection => { :search => :get } map.with_options :controller => 'posts', :action => 'monitored' do |map| map.formatted_monitored_posts 'users/:user_id/monitored.:format' map.monitored_posts 'users/:user_id/monitored' end
这里即有post嵌套关系,也有把 post直接定义成资源,也有传统的controller/action定义。
在其网页上有一个搜索帖子的form表单,其代码如下:
- <form action="/posts/search" method="get">
- <input id="search_box" name="q" size="15" type="text">
- </form>
<form action="/posts/search" method="get"> <input id="search_box" name="q" size="15" type="text"> </form>
这应该是用了routes里的post第二条的定义。
post_controller有一个search方法,如下:
- def search
- conditions = params[:q].blank? ? nil : Post.send(:sanitize_sql, ["LOWER(#{Post.table_name}.body) LIKE ?", "%#{params[:q]}%"])
- @posts = Post.paginate @@query_options.merge(:conditions => conditions, :page => params[:page], :count => {:select => "#{Post.table_name}.id"})
- @users = User.find(:all, :select => 'distinct *', :conditions => ['id in (?)', @posts.collect(&:user_id).uniq]).index_by(&:id)
- render_posts_or_xml :index
- end
def search conditions = params[:q].blank? ? nil : Post.send(:sanitize_sql, ["LOWER(#{Post.table_name}.body) LIKE ?", "%#{params[:q]}%"]) @posts = Post.paginate @@query_options.merge(:conditions => conditions, :page => params[:page], :count => {:select => "#{Post.table_name}.id"}) @users = User.find(:all, :select => 'distinct *', :conditions => ['id in (?)', @posts.collect(&:user_id).uniq]).index_by(&:id) render_posts_or_xml :index end
另外,post_controller里还有第三条routes定义的action----monitored,没细看它是做什么用的。
http://beast.caboo.se/posts
http://beast.caboo.se/forums/1/posts
http://beast.caboo.se/forums/1/topics/1208/posts
都能用,它们都是指定post_controller的index方法,这个方法里构造SQL条件挺巧妙的,
- def index
- conditions = []
- [:user_id, :forum_id, :topic_id].each { |attr| conditions << Post.send(:sanitize_sql, ["#{Post.table_name}.#{attr} = ?", params[attr]]) if params[attr] }
- conditions = conditions.any? ? conditions.collect { |c| "(#{c})" }.join(' AND ') : nil
- @posts = Post.paginate @@query_options.merge(:conditions => conditions, :page => params[:page], :count => {:select => "#{Post.table_name}.id"})
- @users = User.find(:all, :select => 'distinct *', :conditions => ['id in (?)', @posts.collect(&:user_id).uniq]).index_by(&:id)
- render_posts_or_xml
- end
出处:http://www.javaeye.com/topic/118887
- 一个常见REST应用场景的困惑和探究
- token的常见应用场景
- RAC的常见应用场景
- GCD的基本介绍及常见用法和应用场景
- 常见的数据库应用及应用场景
- xargs应用场景和常见用法
- 反射的一个应用场景
- ClassLoader的一个应用场景
- 抢购是如今很常见的一个应用场景,主要需要解决的问题
- 单例模式的常见应用场景
- 单例模式的常见应用场景
- 单例模式的常见应用场景
- 单例模式的常见应用场景
- 单例模式的常见应用场景
- 单例模式的常见应用场景
- 单例模式的常见应用场景
- 单例模式的常见应用场景
- inline-block的常见应用场景
- .Net学习笔记 - 客户端访问服务器端的基本使用
- Java REST框架一览
- 初学者:我的第一个curses程序为何无法编译!
- S3C2410 DMA原理与实例
- Vb.net向sql server数据库中保存图片及图片管理
- 一个常见REST应用场景的困惑和探究
- 高贵之谈
- 如何管理SQL脚本?
- Eclipse开发经典教程:SWT布局(三)
- webservices的一个入门例子
- 排序
- 深入浅出REST
- Eclipse开发经典教程:SWT布局(四)
- 移动应用业务的思考