论坛首页 编程语言技术论坛

也谈一下我对Rails 1.2中 Restful的理解

浏览 20849 次
该帖已经被评为精华帖
作者 正文
   发表时间:2006-12-13  
读了 http://www.iteye.com/topic/38653
想从代码方面谈一谈对Rails 1.2中的RESTful application 的感受。

我有User 和 Article两个Model,并且需要某一个User未读的所有Article。我的第一灵感就是声明一个has_and_belongs_to_many(好长的方法啊,每次都怕敲错)。

class User < ActiveRecord::Base
has_and_belongs_to_many :articles
end

class Article < ActiveRecord::Base
has_and_belongs_to_many :users
end



很简单是吧,那么Controller怎么写呢?

class UsersController < ApplicationController
  def add_unreaded
    @user.articles << @article
  end

  def remove_unreaded
    @user.articles.delete @article
  end
end


等一下,我这么写行不行呢?

class ArticlesController < ApplicationController
  def add_fresh_reader
    @article.users << @user
  end

  def remove_fresh_reader
    @article.users.delete @user
  end
end


这两种写法哪一个好呢?我踌躇,我犹豫,我翻来覆去睡不着觉。
... ...

如果把HTTP之上的所有请求都看成资源的操作的话。add_fresh_reader操作什么资源呢?提这个问题的同时,一个新model浮现了出来:Unreaded 。


class User < ActiveRecord::Base
has_many :articles, :through => :unreadeds
end

class Article < ActiveRecord::Base
has_many :users,:through => :unreadeds
end

class Unreaded < ActiveRecord::Base
end

class UnreadedsController < ApplicationController
  def create
    @unreaded = Unreaded.create(params[:unreaded])
  end

  def destroy
    @unreaded = Unreaded.find(params[:id])
    @unreaded.destroy
  end
end




又见到似曾相识的"create", "destroy"。 如果使用资源的方式思考,我们就会发现,CRUD is everything!

Constraints is Freedom

CRUD 形成了一种约束,把我们从权衡Controller和action风格这种无聊的事情中解脱出来,按照统一的风格来编写程序以及构造URL。使我们有精力关注更重要的事。

REST还避免我们编写大的Controller。可曾有人后悔曾经写过的包含十几个action的,并且action之间毫无联系的Controller呢? 其实大部分情况下,一个Controller有7个action就够了,并且这些action关注于同一Model,大大提高了正交性.

还有什么好处,欢迎大家补充。
   发表时间:2006-12-13  
楼主你的模型有问题吧,article和user通过unread关联,逻辑上有问题啊。读者和文档还可以有更多的关系的。

而且应该记录已读文章吧,假如有人新申请了帐号,你岂不是要把所有的文章都塞到他的未读文章里了?
0 请登录后投票
   发表时间:2006-12-13  
花花公子 写道
楼主你的模型有问题吧,article和user通过unread关联,逻辑上有问题啊。读者和文档还可以有更多的关系的。

而且应该记录已读文章吧,假如有人新申请了帐号,你岂不是要把所有的文章都塞到他的未读文章里了?
你说的没错,有可能有其他关系,但是和Unreaded无关。如果还有其他关系就增加其他新的Models,不能够混在一起。

这个例子还没有涉及到你说的已读文章的需求。你可以在这个例子基础上增加需求来提一个更复杂的例子啊,欢迎补充。
0 请登录后投票
   发表时间:2006-12-13  
有道理。RESTful最核心的部分是“资源”,相关的部分是资源的定位(URI)以及资源的操作(CRUD),尽量把一些复杂的操作转化为CRUD。
0 请登录后投票
   发表时间:2006-12-13  
你难道没有意识到这是一个很严重的问题,这个时候未读文章并不是数据库直接的对象,而是一种关联关系。你这样做是为了restful而restful。

而且本身也不应该用restful解决。最起码不满足url不变性。我没有读过的文章,url/user/123/unread/777(123是我的id,777是文章的id,因为url不变性)。当我读过以后,这个url如何解释?
0 请登录后投票
   发表时间:2006-12-13  
关于多对多关联关系是否应该是Model的问题,DHH的ppt讲得很好,推荐你读一下。

"user/123/unread/777"这个URL不是用来访问Article资源的。正确的写法是 /articles/id
而访问unreaded资源的URL是: /unreadeds/id
0 请登录后投票
   发表时间:2006-12-14  
你这篇和这一篇差不多,不过明显没有他讲的明白。而且明显他的例子更恰当些(用户可以有很多圈子,圈子里面也有很多用户)。
0 请登录后投票
   发表时间:2006-12-14  
多谢指点,其实我这个例子是我项目代码的一部分,直接搬过来了,所以表达效果没有你说的那一篇好。
其实讲得最好的还是DHH的演讲,别的什么都不用看了。
0 请登录后投票
   发表时间:2006-12-14  
dongbin 写道
多谢指点,其实我这个例子是我项目代码的一部分,直接搬过来了,所以表达效果没有你说的那一篇好。
其实讲得最好的还是DHH的演讲,别的什么都不用看了。
dongbin是台湾的兄弟吗,能否介绍几个有关rails或java的台湾论坛,先谢
0 请登录后投票
   发表时间:2006-12-14  
cbmyfirst 写道
dongbin 写道
多谢指点,其实我这个例子是我项目代码的一部分,直接搬过来了,所以表达效果没有你说的那一篇好。
其实讲得最好的还是DHH的演讲,别的什么都不用看了。
dongbin是台湾的兄弟吗,能否介绍几个有关rails或java的台湾论坛,先谢
Faint, 俺是东北人,俺们那尬搭都是活雷锋。
0 请登录后投票
论坛首页 编程语言技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics