新手问题 关于学习 Ruby 的一些问题

sanvi · 2012年08月17日 · 最后由 sanivbyfish 回复于 2012年09月21日 · 9239 次阅读

Ruby 的 Active Record 灰常不好用,加字段和改字段都要重新跑下命令,有没类似 JAVA 的 ORM 框架?

数据库这边是使用 Mongodb 比较好还是 mysql 或者 postgresql

bootstrap 怎么使用起来比较方便

Rails 的 Active Record 其实已经是最好用的 ORM 框架了,加字段,改字段,那是 Rails 的 Migration 作的事情,跟 Active Record 无关。

数据库这边,对于初学者,最好用方便的是 MySQL。

bootstrap 有现成的插件,http://rubygems.org/gems/twitter-bootstrap-rails

#1 楼 @lgn21st 有什么办法就直接改完后数据库那边就自动更改了

在 Development 环境下,你只要改好数据库,浏览器刷新一下,或者 console 里面 reload 一次就可以了。

#2 楼 @sanivbyfish 木有,Java 中的 ORM 是在对象和数据库表之间建立的属性与列的静态对应;而 Rails 的 AR 实际上是在运行时动态解析产生属性,你可以看到除了你使用 Migration 时声明了属性之外模型中其实是可以没有属性声明的。Java 中是先有模型,而 Rails 实际上是先有数据库表

#4 楼 @donnior 也就是说我想加东西只能苦逼的使用 Migration 来加?那用 mongodb 呢?mongoid 这个 gem 好像能 ORM

#5 楼 @sanivbyfish mongodb 是个 schema free 的

#5 楼 @sanivbyfish 可以使用自动 migrate 的 DataMapper http://datamapper.org/ ,但不清楚实践中会有哪些问题。

写 migration 确实苦逼,但这是必要之恶。

#7 楼 @fleuria DataMapper 听说不好,很多问题,也很人都不太推荐,只能苦逼了= =

匿名 #9 2012年08月17日

哎,我觉得直接改数据库更苦逼,东西你开发完以后你还要把数据库跟你的应用一起打包,如果还要进行开发,那就更苦逼了。。。 迁移任务就是让你只需要拿着你的项目代码就可以了,到哪台服务器都只需要执行迁移命令,数据库就搭建完毕。就算你要进行后续开发,要修改数据库也是一样加迁移任务,别人看数据迁移版本就能知道你对数据库做了什么。。。

实际上 Rails 的 migration 脚本是对付 Database Evolutions 的很有效的方法了,Java 中 ORM 的自动更新 schema 的话也不是万能的,如果是持续增加新功能还好说,一旦涉及到原有数据库的修改之类的就苦逼了;更不用说应用还要多地域多版本部署的情况了了,这时候 migration 脚本就成救命稻草了,如果大家有维护和不断修改开发一个系统 3~5 年的话(还有好几种版本),就能体会到 migration 的好处了。。。本人深受其害啊,所以现在在 java 项目中也使用 Database Evolutions 的技术,绝不自动。

我很好奇,通过 migration 脚本的方式改动数据库的 Schema,何来苦逼的感觉?什么样子的方式才是不苦逼?

记得很早的时候,因为项目需要,我曾经维护过一个 Java 的项目,因为项目中没有类似的工具,我建立了一个 dumb 的 Rails 项目去对应 Java 项目中的数据库表,并且用 Rails 的 migration 去改 Schema,并且在 console 中去通过 ActiveRecord 修改表数据。

我觉得 migration 很好用啊,很方便添加,删除,还可以 rollback 不同版本。导入数据库也很方便。已经很智能了。

mongodb 根本就不存在添加字段之说

如果考虑迁移数据库来说 migration 确实非常好用,不过每次更改或者新增都要生成一个文件,跑一段命令,确实很不爽就是了..

#13 楼 @sanivbyfish 等你项目上线要改数据库结构的时候你就知道 Migration 的好处了

JAVA 的哪个 ORM 框架可以做到该表结构后 pojo 不用跟着一起改就能好用的?

#13 楼 @sanivbyfish migration 不是必须的,你不喜欢可以不用,可以像 java 项目那样手工改表结构... 对于无测试,做完就算的项目来说的确 migration 没什么用

#15 楼 @ywjno 都是直接改对象的

#17 楼 @sanivbyfish 那直接改schema.rb以及对应的 migrate 文件应该差不多了吧,用了白名单的顺便把 model 里面也加上字段

或者使用大杀器: 1)导出数据 2)rake db:drop 3)改schema.rb以及对应的 migrate 文件 4)rake db:create 4)导入数据

#18 楼 @ywjno 其实就用他的 AR 就行了,只是习惯下以数据库为主的改动而不是对象

Django 的 orm 支持自动更改数据库,修改模型以后一个同步命令就可以自动新建数据表或字段,用 south 插件也可以自动修改或删除

Migration 比起手动修改数据库要方便的多,但还是有些繁琐,每次修改都要键入模型名和字段名,大小写还不能搞错,比如 guides 中的$ rails generate migration AddPartNumberToProducts后面的AddPartNumberToProducts大小写不能错,名字不能错一个字,也没有相关的命令行自动完成工具

刚才搜 DataMapper 搜到了这个帖子,好像都不提倡用 DataMapper

#20 楼 @gaicitadie

命名问题只能算是小问题了。

Rails 所谓的 ORM/Migration,默认行为还是有不少地方比较坑爹的。

比如开发的时候要改 schema,很可能改错了又要改回来,所以你不会去生成 migration 文件,而是直接去数据库里改。等改得差不多了,想跑一遍回归测试。那就 dump 出 schema.rb。但发布的时候,总该要有 migration 文件的,可是 Rails 默认不提供,比较数据库 schema 和 schema.rb,生成 migration 文件的功能,还完全无视 Foreign Key Constraint。最后,选择开发的时候直接写个 migration 文件,不停改,不停重建数据库。但无视 Foreign Key 这一点完全就是找罪受啊,model 里已经写了一遍了,migration 里还得再写一遍...

而那个 ActiveRecord Query Interface,默认生成的 SQL 可是select *啊,开发的时候的确不碍事,但总不能就这样发布了,还得把所有用到的 column 名字都补回去,下次改到这里再注释掉。要不就不用 ActiveRecord Query Interface。

数据库这边是使用 Mongodb 比较好还是 mysql 或者 postgresql

凡是问这个问题的,答案一律是 Postgres

#22 楼 @knwang 说是这么说,但问题是没发现有 ORM 能充分发挥 PostgreSQL 的优势啊

#23 楼 @bhuztez 能想到要充分发扬 PostgreSQL 的是不会问这个问题的。

Rails 4 会支持 Postgres 的 Array type, 现在应该有 gem, 找找看。

#24 楼 @knwang Rails 你都好意思搬出来说,Rails 3 可是连 Foreign Key 都不会建的,都好意思说自己是 ORM。

没有原生支持的结果是,第三方库一般都不会用这些特性,差不多就等于,全都得自己改过。所以当然会有这个问题啊。

#25 楼 @bhuztez 真抱歉啊 rails 这么挫你还整天泡在这里。

#21 楼 @bhuztez 看不懂你什么意思,改数据库为啥不生成 migrate?想改回来直接 rollback 就 OK 为啥非要直接改数据库

#26 楼 @Rei 难道这里是 Rails-China?还是 Ruby===Rails?

#25 楼 @bhuztez

估计你可能是数据库背景的吧。如果你说的是 foreign key constraint,Rails 不是不会建,是选择不建。绝大多数的 app 这种选择是合适的。如果需要建也很容易。就好像 Java 说,你 Rails 连 Messaging, Scheduling 这些东西都没有,还好意思说自己是 web framework。一个道理。框架的哲学和取舍不同。

而且你的 app 做到一定程度,是一定会对架构进行特制的。任何再好的 ORM, web 框架都不能包你到底

#29 楼 @knwang 要自己写 SQL 建的也叫会建?对大多数 app 建不建区别不大。但是从数据库角度看,没特别理由,你都应该建才对啊。你自己去看 Rails 之前的讨论,默认不建,完全就是为了向 MyISAM 妥协,而不是因为这样的选择是合适的...

#27 楼 @jjym 有个问题就是,一次 commit 如果动了多个 column,而开发的时候是分多次改的,会生成多个 migration 文件,回头来找不太方便。我想在改完,commit 进仓库之前,把这些 migration 的内容合起来。

#30 楼 @bhuztez 如果你想说 Rails 设计有不合理的地方,我非常同意你。但这对原来提问作者没有任何帮助。我前面说的是,如果在数据库选择上犹豫,说明原作者的项目并不是很明显有利于用基于文档的数据库,或者作者对这些数据库本身并不是很懂,这样选择 PostgreSQL 合适

#31 楼 @bhuztez 回头找很方便,用 git log. 我同意 @jjym 的建议

#31 楼 @bhuztez 谁去看 migration 文件啊?都是看 schema.rb 的...

#33 楼 @hooopo 当然会看啊,有时候,你不知道这个 column 是怎么来的

#34 楼 @bhuztez 版本控制是干什么的

#32 楼 @knwang 所以还是直接改数据库了。因为 rollback 完还要自己把那 migration 文件给删掉。还不如全都改完了 diff 一下 schema.rb,自己照着写个 migration 了。但其实这个 Rails 能搞定的,也应该由 Rails 搞定的。

就算这样也没 Foreign Key,还有其他一些 Constraint 什么的,于是就不如直接写 migration 文件,而不是用 Rails 生成了..

#20 楼 @gaicitadie 什么大小写不能错?和起名字没关系好不好。都是自动生成的,你愿意起什么名字就起什么名字:

rails g migration migration_name_here

#37 楼 @hooopo 我觉得他的意思是这样就不会自动生成内容了吧

比如开发的时候要改schema,很可能改错了又要改回来,所以你不会去生成migration文件,而是直接去数据库里改

小白才直接去数据库里改..

#39 楼 @hooopo 小白才不敢去数据库里改吧...

#28 楼 @bhuztez 我不用跟你抠字眼,你在 ruby china 的发帖套路不就是「默念:哟西这个 Rails 默认没提供」 -> 「大声:Rails 太挫了这个都做不到」 -> 别人指出方案 -> 「不行这不是我要的」-> 影遁消失 -> loop

有些人可能脑容量有限或者气量比较小,积累了一些知识就学不进新东西了,这也没问题,把自己已知的钻研到极致,多写些分享也是一大贡献。不过专门找着自己不了解的东西黑,吃相难看啊。

正题,官方文档给的加外键的方法

http://guides.rubyonrails.org/migrations.html#active-record-and-referential-integrity

Although Active Record does not provide any tools for working directly with such features, the execute method can be used to execute arbitrary SQL. You could also use some plugin like foreigner which add foreign key support to Active Record (including support for dumping foreign keys in db/schema.rb).

#35 楼 @hooopo 不总能用到版本控制啊。有时候你是按版本发布 tar 包的

#41 楼 @Rei 我就问你有多少比例的第三方 Rails 项目用了 foreigner 之类的东西,Ruby Taiwan 都是没用的吧

#43 楼 @bhuztez 他们觉得不需要也不能逼着他们用啊,要不要用得看场景。

而那个ActiveRecord Query Interface,默认生成的SQL可是select *啊,开发的时候的确不碍事,但总不能就这样发布了,还得把所有用到的column名字都补回去,下次改到这里再注释掉。要不就不用ActiveRecord Query Interface。

小白才去挨个加 column 名字... 小白才不用 ActiveRecord Query Interface。

#44 楼 @Rei

默认不建 Foreign Key 这个行为就是 Rails 早期版本的残留。

但是,甚至连 @knwang 都以为

如果你说的是 foreign key constraint,Rails 不是不会建,是选择不建。绝大多数的 app 这种选择是合适的。

而事实上,Rails 很早就不赞成不建 Foreign Key 这种做法了,在文档里肯定会告诉你该怎么建 Foreign Key 的。但是为了迁就 MyISAM,Rails 就是不建 Foreign Key,哪怕你用的是 PostgreSQL 或者 InnoDB。

#38 楼 @bhuztez 既想拼错单词,又想自动生成内容。。

#46 楼 @bhuztez 所以你的观点是?

#45 楼 @hooopo Rails 又不会在你用 migration 加了一个 column 之后,自动把你记录各个 column 名字的变量也作相应的修改。Rails 能知道你新加了个 column,就是因为用了select *。所以,开发的时候,你不得把相关的代码给注释掉,不然加了个 column,还得去改 model 部分代码。得发布了又得把新增的 column 名补上。现在,还有谁敢拿着里面还有select *的代码去发布啊,现在都找不到多少 PHP 代码里面到处都是select *了吧。

#47 楼 @hooopo 反正这是他的想法,不是我的。我觉得他没找对该吐槽的地方,就补上了。

#50 楼 @bhuztez

命名问题只能算是小问题了。

你是同意了的啦。

#49 楼 @bhuztez 用不用 select * 和静态文件要不要打包到一个文件这种问题还有讨论的必要么。

#51 楼 @hooopo 这个是有点不爽,既然 Rails 都要宣扬 CoC 了,名字 Rails 自己生成一个就是啦,我才不要自己指定名字,我要 Follow 你的 Convention。比如命令长得这样就好了嘛

rails generate migration add product part_number:string

但也不至于被这个坑到,因为写错了,马上就知道了。会被坑到才算值得注意的问题。

#48 楼 @knwang 默认就建 Foreign Key 啊,别整个第三方的 gem,不然很多人就干脆不建 Foreign Key 了。不该迁就 MyISAM 这种功能不全的数据库引擎。

SQL 有啥功能,都要能在 ORM 里能体现出来。默认没有,很多第三方库就不会去用。差不多就相当与是把 RDBMS 当 key-value 存储用,这样,就会有人觉得 RDBMS 不好用。这也不难解释,现在有很多人会去折腾 MongoDB 这种适用范围很窄的东西。

Rails 核心开发者又不是水平不行,也不是相关部分的代码没写好,但就是能经常搞这种默认就不给你启用这种事情出来。还说啥 Rails 的默认设定是适合大多数人的,你没设对就是你水平不行,总之就是你自己的错。非要等到出事了才肯改一下默认设定。Rails 3 都号称 Secure by Default 了,还能连改 mass assignment 的默认设定都极不情愿。

不管怎么说,还是在往积极的方向发展么。模板默认会 escape 了,mass assignment 默认会过滤了。SQL 注入的问题也暴露出来了,补丁也有了。希望早一点能:默认只用数据库的客户端库来 escape,别自己 escape 了以及在参数上搞点花样,Foreign Key Constraint 默认能给我建好,除非我特别指定,别给我生成SELECT *这样的 SQL 出来。

哈哈,戳出血了~ RT #47 楼 @hooopo 既想拼错单词,又想自动生成内容。。

  1. ActiveRecord 这东西,有好处、有局限,这没办法,框架就是这样的。否则,自己去写框架好了(满足了自己,一定有别人不满)
  2. 数据库哪个好,要看应用究竟是什么。我真心喜欢 MongoDB 这类 NoSQL,尤其是我要处理大量文本标记的时候,SQL 直接就废了。
  3. 完全没有人回答第三个问题啊…… a) 看文档;b) 在编辑器(比如 textmate, sublime text 2)中积累 snippets,就会越写越快。

另外,不要吵架么。呵呵。有人说话不好听,直接不理就算了。 不知道论坛能不能给每个用户一个属性:"人品",然后大家投票?哈,这功能一定很坑爹!

用 mongodb 吧

#56 楼 @xiaolai 支持这个功能,人品低的用户字体自动变小!

代刷人品啦,一袋小浣熊方便面一人品

#59 楼 @jjym 哈,“人品低的用户字体自动变小”,这个“执行”既可行又可笑,还有效!哈,笑死我了。

#61 楼 @xiaolai 也可以字体颜色变浅...

@hooopo @jjym AVFUN 的思路不是挂上去置顶么。。。

围观至此 人品功能 +1

#54 楼 @bhuztez

首先你的不满是针对 Active Record, 而不是整个的 Rails。Active Record 作为 Rails 的缺省配置是要做到对大量数据库,包括不支持 foreign key constrant 数据库的基本支持,所以不对某一个,或某一类数据库作优化。Rails 3 松动了各组件,你可以替换用你喜欢的。如果不喜欢 ActiveRecord 的库但喜欢其基本样式,可以考虑Sequel。按照你的喜好,我建议你尝试datamapper - 不用 Migrations 而且可以建 foreign key constraints。但是自动更新的 Schema 并不是万能 -详细请看 Data Mapper 里面的讨论。

我对 Active Record 也有不满之处,但更多是它容易使存储逻辑和业务逻辑混在一起,尤其对于没有经验的新手,很容易认为两者没什么不同,造成项目中后期维护困难。但我还是会出于维护和周边生态系统支持的原因选择 Active Record, 只不过在我的 ActiveRecord::Base 对象里面几乎没有任何业务逻辑。供你参考。

对已有功能的不满是新软件问世的动力,Ruby 圈里很多很厉害的都是源自于牢骚。我和一个前同事曾经想过做一个专门针对 PostgreSQL 的 ORM, 但也一直没时间做。如果你对这个感觉强烈你可以考虑自己做,绝对很有很大的市场。做好了估计 Heroku 会直接把你招进去,和 Matz 做同事。别停留在牢骚。

Foreign Key Constraint 默认能给我建好,除非我特别指定,别给我生成 SELECT *这样的 SQL 出来。

不知道你是不是在开源圈子里面时间短。开源贡献者都是用自己的时间自愿写软件,又拿出来免费给社区用。没有人欠你什么。你不爽,自己另立门户好了。这种大爷感没什么意思

@bhuztez

所以,开发的时候,你不得把相关的代码给注释掉,不然加了个column,还得去改model部分代码。得发布了又得把新增的column名补上。现在,还有谁敢拿着里面还有select *的代码去发布啊,现在都找不到多少PHP代码里面到处都是select *了吧。

你举 PHP 的例子要说明什么?PHP 程序员都是最勤劳、最不怕干脏活儿、累活的同志啊。这一点大家都知道。

可以新开一个贴讨论一下 select *和外键约束问题..这贴太乱了。

其实楼主已经用 mongodb+mongoid 了 datamapper 看到很多都不推荐 其实对小项目来说,mongodb 和 postgres 或者 mysql 都区别不大,都是存数据而已嘛

对我一个 javaer 来说,最无缝的还是 mongoid 感觉跟以前用 orm 差不多

不过只是需要重新投入学习 mongobd 的语法的成本罢了

hooopo SQL 通配符真的很糟糕么 提及了此话题。 04月12日 11:27
需要 登录 后方可回复, 如果你还没有账号请 注册新账号