@
imn1 你这想法基本就是停留在表面,根本没有深层次的思考。细节决定成败。
@
breestealth 根本就不是语言层面的差距,而是整个生态环境的差距。
@
TangMonk 我没有深入了解过node,估计你也没有深入了解过吧。某次ruby聚会上,某个女程序员对node的module的吐槽,各种坑,和ruby比简直天差地别
@
wangdaimishu 收集表单数据我知道,我说的不是这个。YII查询貌似也不需要非要传递一个CDbCriteria,而且传递CDbCriteria也没有什么不妥的。
而且我在刚开始用Rails的时候甚至觉得觉得缺少一个类似这样的玩意。
(用在哪个场景我忘了)
而真正是在多人协同的时候,需要同步表结构的时候,问题就来了。
开发A在表a增加了一个字段,开发B在表a增加了另外一个字段,这时候怎么同步呢?最原始的方法是用navicat手工同步,一条一条比对,极其容易出错,当表结构变化超过5次,已经没人能说的清誰先谁后、哪个是最终正确的表结构了。
我在用自己的框架的时候也有这个问题,我在各种php论坛、群里询问这个问题,多方查资料,线下咨询。(因为当时还是想做自己的框架)
觉得应该可以做成“表结构版本控制”的东西,把表结构变化文件化,然后用git等版本控制工具同步变化。
后来发现rails里面的migration好像就是这个玩意。
然后想到Django里的syncdb 好像也是做这个的,当时回想起n年前买过一本Django的书,里面明确说明“Django是很智能的,即使你在文件里写明了删除某个字段,实际syncdb也不会删除,为了避免部署的时候删错东西”,我简直瀑布汗。。。。
(后来我也没有去考证到底在哪一页,python的书我基本都扔了,就留了一本python cookbook)。
刚刚我又搜了一下The Django Book,找到了类似的东西
http://djangobook.py3k.cn/2.0/chapter05/~~~~~~~~~~~~~~~
syncdb 命令是同步你的模型到数据库的一个简单方法。 它会根据 INSTALLED_APPS 里设置的app来检查数据库, 如果表不存在,它就会创建它。 需要注意的是, syncdb 并 不能将模型的修改或删除同步到数据库;如果你修改或删除了一个模型,并想把它提交到数据库,syncdb并不会做出任何处理。 (更多内容请查看本章最后的“修改数据库的架构”一段。)
~~~~~~~~~~~~~~~
不过我没找到“修改数据库的架构”这一段。
我研究python的web开发主要还是在2010年左右,可能现在python社区有解决方案,只是我不知道(请谅解)
然后某天看到YII里也有migration,但是这明显是一个后补进的设计,因为YII并没有强制使用migration来生成表结构,也许是为了好上手吧。
但我们可以强制团队必须使用migration,于是流程是什么呢?
1 写migration文件
2 运行migration ,生成表结构
3 根据表结构生成model文件
而rails是
1 rails g model model_name 直接生成model文件和migration文件
2 写migration文件
2 $rake db:migrate 根据建立表结构
由此可以看出来YII的migration是可以砍掉的,目的是为了某些不想写migration或压根不想了解migration的人,手工建表也可以使用yii框架的其他功能。
而Rails则是赤裸裸的由ruby代码+ruby命令行来控制一切。
此时我们比较一下2个model文件
发现rails的model只有2行
1 class SourceHtml < ActiveRecord::Base
2 end
而YII的model里面洋洋洒洒。
这时候你说了,YII的model里面写的东西可以用来写验证和生成表单,Rails其实也是可以的。
然后我们看看YII的model里写了多少无趣的东西
public static function model($className=__CLASS__)
{
return parent::model($className);
}
每个方法在model里面都有,OMG!
dont repeat your self好吗?
我自己的的框架里是不需要定义这个方法的,因为
我的ActivRecord里是这样写的
static public function model(){
$class_name = get_called_class();
if (is_callable("{$class_name}::instance")) {
return $class_name::instance();
}
return new static;
}
而YII的CActiveRecord是这样的
public static function model($className=__CLASS__)
{
if(isset(self::$_models[$className]))
return self::$_models[$className];
else
{
$model=self::$_models[$className]=new $className(null);
$model->attachBehaviors($model->behaviors());
return $model;
}
}
对比了一下我知道为什么了,用new static的做法在IDE没有智能提示的,所以YII妥协了,要显式的传递一个__CLASS__进去
而我又在model里发现了这样的东西
public function rules()
{
return array(
array('user_id, last_time, last_ip', 'numerical', 'integerOnly'=>true),
array('player_name', 'length', 'max'=>255),
array('id, player_name, user_id, last_time, last_ip', 'safe', 'on'=>'search'),
);
}
public function attributeLabels()
{
return array(
'id' => 'ID',
'player_name' => '玩家昵称',
'user_id' => '平台用户',
'last_time' => '最后登录时间',
'last_ip' => '最后登录ip',
);
}
这意味着什么?这些代码都是由表结构生成的。我不知道把表结构复制出来一份放到model里的意义何在。
于是我们需要修改表结构的时候,要酱紫
1 写migration
2 运行migration
3 ?
运行完migration之后,model里的rules() attributeLabels() 是不会改变的,model里的代码需要手工再修改一遍,而且绝对不止这两个method。如果表结构修改比较多,呵呵。。。
当然你可以运行gii什么的,重新生成一遍model文件,但结果是,自己手工写的代码会被覆盖掉。所以这个操作是个绝对危险的动作。
所以也有很多人php开发不喜欢用框架。
其实原因是:用不合理的设计,搞了一堆一堆半半拉拉的自动化工具,做了一个蹩脚的不完整的解决方案,还楞要人家学习和使用。用的人不烦才怪。
80% * 80% * 80% = 51.2% , 还不及格
我还见过更极端的,坚决不用YII,要用YII他就闪人。
我不知道Laravel是个什么情况,看过文档,基本算是rails在php这边做的复制吧。
不过既然有了iPhone,谁还用小米。
年前某个公司boss让我带团队,我说用ruby吧,他同意了,后来又反悔了,团队已经学了并用rails做项目一个月了,丫硬非要改回php。直接闪人。
还是那句话“细节决定成败”,python node go php 基本都看过了,不是单是语言好坏,主要在于社区气质,只有ruby社区是最有追求极致的气质,果断皈依。