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

终于知道rails单复数的规则了。

浏览 12035 次
精华帖 (5) :: 良好帖 (0) :: 新手帖 (7) :: 隐藏帖 (6)
作者 正文
   发表时间:2007-11-15  
activesupport-1.4.4\lib\active_support\inflections.rb


Inflector.inflections do |inflect|
  inflect.plural(/$/, 's')
  inflect.plural(/s$/i, 's')
  inflect.plural(/(ax|test)is$/i, '\1es')
  inflect.plural(/(octop|vir)us$/i, '\1i')
  inflect.plural(/(alias|status)$/i, '\1es')
  inflect.plural(/(bu)s$/i, '\1ses')
  inflect.plural(/(buffal|tomat)o$/i, '\1oes')
  inflect.plural(/([ti])um$/i, '\1a')
  inflect.plural(/sis$/i, 'ses')
  inflect.plural(/(?:([^f])fe|([lr])f)$/i, '\1\2ves')
  inflect.plural(/(hive)$/i, '\1s')
  inflect.plural(/([^aeiouy]|qu)y$/i, '\1ies')
  inflect.plural(/(x|ch|ss|sh)$/i, '\1es')
  inflect.plural(/(matr|vert|ind)ix|ex$/i, '\1ices')
  inflect.plural(/([m|l])ouse$/i, '\1ice')
  inflect.plural(/^(ox)$/i, '\1en')
  inflect.plural(/(quiz)$/i, '\1zes')

  inflect.singular(/s$/i, '')
  inflect.singular(/(n)ews$/i, '\1ews')
  inflect.singular(/([ti])a$/i, '\1um')
  inflect.singular(/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i, '\1\2sis')
  inflect.singular(/(^analy)ses$/i, '\1sis')
  inflect.singular(/([^f])ves$/i, '\1fe')
  inflect.singular(/(hive)s$/i, '\1')
  inflect.singular(/(tive)s$/i, '\1')
  inflect.singular(/([lr])ves$/i, '\1f')
  inflect.singular(/([^aeiouy]|qu)ies$/i, '\1y')
  inflect.singular(/(s)eries$/i, '\1eries')
  inflect.singular(/(m)ovies$/i, '\1ovie')
  inflect.singular(/(x|ch|ss|sh)es$/i, '\1')
  inflect.singular(/([m|l])ice$/i, '\1ouse')
  inflect.singular(/(bus)es$/i, '\1')
  inflect.singular(/(o)es$/i, '\1')
  inflect.singular(/(shoe)s$/i, '\1')
  inflect.singular(/(cris|ax|test)es$/i, '\1is')
  inflect.singular(/(octop|vir)i$/i, '\1us')
  inflect.singular(/(alias|status)es$/i, '\1')
  inflect.singular(/^(ox)en/i, '\1')
  inflect.singular(/(vert|ind)ices$/i, '\1ex')
  inflect.singular(/(matr)ices$/i, '\1ix')
  inflect.singular(/(quiz)zes$/i, '\1')

  inflect.irregular('person', 'people')
  inflect.irregular('man', 'men')
  inflect.irregular('child', 'children')
  inflect.irregular('sex', 'sexes')
  inflect.irregular('move', 'moves')

  inflect.uncountable(%w(equipment information rice money species series fish sheep))
end

   发表时间:2007-11-15  
太有用了 收藏
0 请登录后投票
   发表时间:2007-11-25  
很早了,那时候一看到就把它转成了csharp,cpp,java
0 请登录后投票
   发表时间:2007-11-25  
rails在整个框架上对单复数区分动作太大了.
我觉得,rails作者坚不可摧的自信是它成功的根源,许多优秀的开源/商业项目就是因为缺少对自已能力、判断力的信心而走向歧路。但如果自信没有建立在雄厚的经验和能力的基础上,就是武断。
说回单复数,rails的REST风格惯例,是controller为复数,url为复数,这跟传统的风格不一样,有几个网站的url是复数的啊?原因在于,在一些特定情况下,概念的含义必然是复数形式,不必显式声明,像url,文件目录,它作为若干对象的容器必然被人们理解为复数,显示声明反倒不符合"convention over configuration"的原则。同理controller。虽然routes里有singleton resource的概念,也不应该是复数url存在的理由。
再者,model文件/类又用单数,跟controller相对照也显得不一致。 似乎rails开发团队没有意识到这个问题?还是有更充足的理由?
BTW:
iteye.com/forum(s) 这个s就看着很拐扭
iteye.com/topic/140895 看着就舒服的多

0 请登录后投票
   发表时间:2007-11-25  
对头,我也觉得controller没必要搞成复数形式。
0 请登录后投票
   发表时间:2007-11-25  
liusong1111 写道
rails在整个框架上对单复数区分动作太大了.
我觉得,rails作者坚不可摧的自信是它成功的根源,许多优秀的开源/商业项目就是因为缺少对自已能力、判断力的信心而走向歧路。但如果自信没有建立在雄厚的经验和能力的基础上,就是武断。
说回单复数,rails的REST风格惯例,是controller为复数,url为复数,这跟传统的风格不一样,有几个网站的url是复数的啊?原因在于,在一些特定情况下,概念的含义必然是复数形式,不必显式声明,像url,文件目录,它作为若干对象的容器必然被人们理解为复数,显示声明反倒不符合"convention over configuration"的原则。同理controller。虽然routes里有singleton resource的概念,也不应该是复数url存在的理由。
再者,model文件/类又用单数,跟controller相对照也显得不一致。 似乎rails开发团队没有意识到这个问题?还是有更充足的理由?
BTW:
iteye.com/forum(s) 这个s就看着很拐扭
iteye.com/topic/140895 看着就舒服的多




REST的全称Representational State Transfer(表述性状态转移),表述什么的状态?当然就是资源,如网站上有一种称为post(帖子)的资源:
/posts,是表示所有的帖子
/posts/11,可以理解所有帖子中id为11的

而我们中国人的习惯说法却是类似“小杨,麻烦帮我找下11号那份档案”,对应的url形式则为:
post_11
或结构化为:
/post/11

如果要表述“热门的帖",按照中文得到的字面翻译则是:
/hot_posts

而按照REST的风格就是:
/posts/hot,也就是“在所有posts中算是热门的”

看到好处了吧?REST风格不但能符合自然语意(in English),而且也符合“资源”的存放、组织形式(可以想象一下我们硬盘上的目录结构):
posts/hot
posts/recent
posts/xxx
...


再说如果没有符合英语形式的单复数约定,怎么能做到“代码即文档”?
对于熟悉英语的人来说,阅读Rails的代码是很“字面化”的,如 User.has_many :posts; User.has_one :avatar,读码一遍,其义立见。
0 请登录后投票
   发表时间:2007-11-27  
单复数纯粹是英语的问题。。。。。。。。。居然也能扯上什么“代码即文档”。。。。。。。。
0 请登录后投票
   发表时间:2007-11-28  
我想的太过简单和依赖直觉了,rainchen很有道理.

同时我也十分赞同dualface的说法,对于不区分单复数的自然语言,表达这种关系更容易,问题直接牵扯到自然语言与程序语言的映射.

rails REST支持的典型CRUD和自定义的动作,都会区分是作用于单数(member,个体)还是复数(collection,集合)之上,而rails的惯例是/posts表复数,/posts/1表单数.  这种用/posts/1而不是/post/1表示单数多少跟英语的自然表达有些出入,但把/posts看成是directory时又很容易解释通. 汉语当中,当一个术语表示类属时,通常不用加"们",英文却常常要这样表达: bring your toy(s) here.
如果单数/post/1 复数/posts呢? 又有过于追求自然语言而放弃一致性的嫌疑.

现有多数web系统不使用复数形式我猜有两个原因:
1. 现存mvc框架多以单数形式约定,且没有从REST(resource)的角度设计.
2. 使用英语单数也可接受.

分析/posts/hot的单复数部份,更容易分辨出哪部份是mvc的controller,哪部份是action.(这个直观性我觉得也很重要,不知道是我REST体会不够深入,还是MVC的魅力)
不过,如果id都是整数形式,单复数分别表达为 /post/1和/post,根据后面有没有带数字也很容易区分是哪种.

url/directory是树形的组织结构,多用来表达很强的种属(category)概念(名词形式).
web 2.0的label采用更灵活随意的结构,文字描述上名词形容词都常见.
url/directory的末端,可能代表一个具体的对象,比如/movies/prison_break/S01E04.rmvb, prison_break就代表一个具体的电影而非种属.
如果把种属(category)意义的url/directory归结为namespace而非resource,显然太不友好.

我接触过的web系统,基于种属(category)概念之上的单复数占多数,上面提的prison_break那种占很小一部分.
我个人更喜欢默认全部单数形式表达这些概念,既然引入复数形式投入了成本又没有完全解决麻烦.
时髦说是less is more

话又说回来,不管怎么约定,根源还是那万恶的英语,吹毛求疵在论坛大搞学究,跑回工程中反倒觉得哪种都无所谓,只要大家风格一致就好. 回去猛背 xx(s)_path那些看起来美好的helper,希望它能荡平前方的妖魔鬼怪. rails升到2.0,这些helper名字的约定变了,一不小心,自己人成了妖魔鬼怪. 新一轮的战斗开始了,这就是青铜圣斗士们的命运:生命不息,战斗不止,百打不死,@#$^&

rails惯例中,model映射的table名是复数,这一点实在难以接受. 一个table放多条记录不是天经地义的吗,非要体现在名字上真是令人匪夷所思.
虽说一个pluralize_table_names配置项就搞定,可一批generator就开始不灵光了. 我觉得table名用复数形式是完全没道理的,就不该有这个选项,全部单数就清爽的很,反倒table_name_prefix这样的选项还可能有点用处.

问题1: rails REST routes的namespace该用单数还是复数呢?

www.iteye.com/forums 如果把forum理解成版面可以解释通,否则,应该是singleton resource概念的forum

0 请登录后投票
   发表时间:2007-11-28  
确实有这个烦恼。虽然我是搞php的,但php里面的cakephp也学ror,搞什么单数复数。偏偏英文单词复数形式并不只是加个s就好,还有不少规则和特例。

我觉得如果应用本身是为中国人开发的,根本不用在乎是单数还是复数。。。只要好用就行了。如果是国际化的应用,倒是需要注意这个问题,但就像前面说的,有些地方你觉得单数好,但换个角度看又是复数好。。。。。
0 请登录后投票
   发表时间:2007-12-13  
呵呵,其实Rails的单复数约定好不好呢,个人认为习惯了就好。

著名JAVA框架Spring的大牛就这样评击过ROR:
http://stone4102.itpub.net/post/14736/101347
引用

6、你对Ruby on Rails的看法如何?
Spring MVC:RoR非常有趣。不过现在就拿出来用还有点幼稚。这里举了个例子,关于变量的复数形式的处理,RoR会使用这样的CoC风格来处理变量list,而Spring MVC也实验了种种风格,但是受到的结果却很差。人们认为英语的复数很古怪,没有一定的规则,所以会带来混乱,如(person -> people)。所以Spring MVC设计了变量+List的命名,personList更加明确,虽然这样不酷,但更好用。就是说Spring MVC要取其精华去其糟粕。


我觉得最尴尬的情形会是如此:
<% for news in @news %>
  <%= news.title %>
<% end %>


对ROR没什么问题,但对于php呢?
<? foreach($news as $news): ?>
...
<? endforeach ?>


因此有时是需要“量力而行”。

觉得复数比单数别扭?但在我们眼中“请给我两只苹果们”就如在老外眼中的“Please give me 2 apple”一样别扭。


另外我觉得liusong1111你对REST的理解简化了,RAILS里的RESTFUL强调的是资源操作,而不是简单的ACTION,如posts/1,其实是包含了request mothod的,如一般的GET posts/1,映射的是posts/show/1,show才是action; PUT posts/1 => posts/update/1
0 请登录后投票
论坛首页 编程语言技术版

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