http://railser.cn/
最近的一个网站单子里,需要给客户用discuz7.2实现一个会员功能,dz是大品牌,何况康盛又被腾讯收购,质量应该可靠。所以反复衡量,dz成为首选了。(跟DZ和康盛的系列产品源渊太多了。)
客户提出的问题还算顺利的一一解决,客户最后提出一个要求,要对最新的消息有一个提示。这个实现很简单,给客户讲解了如何设定声音,可是问题来了,我这里怎么都听不到声音,客户那里也是如此。
怎么会这样,开始我以为是我浏览器的问题,但是几个浏览器测试都无声,这个是绝对不应该的。代码是官网下载的discuz7.2 utf8。什么情况?怎么办?
网上查了一下竟然很多人反馈了这个问题,可是没有几个提出解决办法的,有两篇的解决办法尝试了一下,没有解决问题。难道是我的特例??
外包方式开发最可怕的是耽误进度和过多的向客户解释,为客户选择的产品,如果质量不过关,影响的绝对就是制作方的信誉。
现在问题来了,如何解决。
解决办法:
1、先参考官方提供的一个解决办法,仅做参考,因为它也没解决问题。所以我真不知道官方的维护是干什么吃的。
http://www.discuz.net/forum.php?mod=viewthread&tid=1523437&page=7#pid12811924
2、因为mp3,wav等格式均无效,我让合作的美工把声音文件转成了swf,可以在这里下载。
3、按照上面那篇提示文章,修改一下对应的文件,引用改成swf,并且简化swf的文件引用,因为那个player已经无用了,直接引用swf声音即可。下面是代码,希望能帮助一些朋友。
templates/default/memcp_profile.htm 499行
$('soundplayerlayer').innerHTML = AC_FL_RunContent('id', 'pmsoundplayer', 'name', 'pmsoundplayer', 'width', '0', 'height', '0', 'src', '{$boardurl}images/sound/pm_'+file+'.swf', 'menu', 'false', 'allowScriptAccess', 'sameDomain', 'swLiveConnect', 'true'); }
templates/default/pm_checknew.htm 可以不改动,因为在我的方案里它已经没用了,如果有尝试的朋友,可以对应替换这段代码
<script type="text/javascript" reload="1">$('pmsound').innerHTML = AC_FL_RunContent('id', 'pmsoundplayer', 'name', 'pmsoundplayer', 'width', '0', 'height', '0', 'src', '{$boardurl}images/sound/pm_$pmsound.swf', 'menu', 'false', 'allowScriptAccess', 'sameDomain', 'swLiveConnect', 'true');</script>
两段代码的含义是一样的,都是直接引用swf声音文件。
templates/default/header.htm 在40行位置,增加
<span id="pmsound"></span> <!--{if $prompt}--><script type="text/javascript" reload="1">$('pmsound').innerHTML = AC_FL_RunContent('id', 'pmsoundplayer', 'name', 'pmsoundplayer', 'width', '0', 'height', '0', 'src', '{$boardurl}images/sound/pm_$pmsound.swf', 'menu', 'false', 'allowScriptAccess', 'sameDomain', 'swLiveConnect', 'true');</script><!--{/if}-->
此段是解决问题的关键,注意蓝色的部分,论坛代码里是缺失这个的,经检查,pm_checknew里的执行结果被插入到id="append_parent"的一个 div中,而且,里面的<!--{if $s}-->是无效的。
4、到后台更新缓存,重新测试,声音提示成功。
从发现问题到解决问题经历了几天的时间,这里问题解决不了,终究不能卡住不前的。所以选择好的产品,使用正确的方法,实在太关键。康盛将太多的心思用到了一些花哨的功能上,代码质量一直未见提高,产品硬伤内伤依旧,一个画皮一样的产品,只能靠忽悠来支撑了。
rails new 特定版本
rails _3.0.7_ new railstest
说明:安装多个版本,尤其安装了3.1.0 pre 后,使用Rails 3.0.7这个最新稳定版开发项目。
crontab的写法误解
crontab的标准写法参照这里,http://www.centos.org/docs/5/html/Deployment_Guide-en-US/ch-autotasks.html
那么,每阁特定小时运行命令如何写呢?
每隔30分钟,运行一次命令,可以写
*/30 * * * * /sbin/do_something
每隔4小时,可以写成
* */4 * * * /sbin/do
吗?不可以,这样会产生很严重的错误,导致我每分钟运行一次命令,直到某种情况下被中止。想到这我真心疼我的mysql和cpu。
这里正确的写法应该是
0 0,4,8,12,16,20 * * * /sbin/do (whenever 给出的写法)
或者
0 */4 * * * /sbin/do (我认为可行的写法,不过至今未确认,这个写法可以从保存时开始,每隔4小时执行一次)
两个写法,都要在第一个位置,指定执行开始的分钟数。
请各位指正,我也继续验证一下我的写法。
readline load error的解决办法
服务器总算都调试完了,今天打算看一下一个app的具体信息,发现 rails c提示错误。
这是个常见的错误:`require': no such file to load -- readline (LoadError)
原因:缺少readline
解决办法:进入rvm ruby1.9.7的src,安装readline
具体:
>> which ruby
/usr/local/rvm/rubies/ruby-1.9.2-p180/bin/ruby
>> cd /usr/local/rvm/src/ruby-1.9.2-p180/ext/readline
>> ruby extconf.rb
>> make
>> make install
再次rails c,解决问题了。
笔记太有用了,都省去了回忆的时间。
在CentOS5上部署Rails3应用
1、安装rvm
安装rvm前,要先安装git。因为rvm的安装教程就是一个git的小脚本。
>>wget http://kernel.org/pub/software/scm/git/git-1.7.5.3.tar.bz2
Oop!这里有个问题,我tar不常用,这里tar xvfz git-... 是会提出格式错误的,查了一下需要换一个命令:tar -xvjpf git-...
之后,
make prefix=/usr/local all
make prefix=/usr/local install
看到git 版本后,安装rvm
git --version
剩下的,就是按照 https://rvm.beginrescueend.com/rvm/install/ 的讲解一步步安装吧,最后,阿?为什么
type rvm | head -1
会提示错误呢?我也被搞糊涂了,按照提示,我重新打开一个终端窗口,这下正常了。所以再看看文档吧。
接着,安装1.8.7
2、安装ruby 1.8.7和gem
rvm install 1.8.7
注:我又将用户切换回了root,而在进行到Load RVM into your shell sessions as a function的时候,我不得不切换回user。
rvm use 1.8.7
显示正常了。
安装gems
http://rubygems.org/pages/download
3、安装rails
gem install rails -v 3.0.7 --no-rdoc --no-ri
如果安装rdoc和ri,我出现了问题,具体的情况未明。
问题又来了,>> rails -v 找不到命令
翻看文章的过程中,有一句话很重要,“gem install rails # 注意不要加sudo,否则会安到系统的ruby下,而不是rvm的ruby下”
这是在百度里查到的,可是不用root,rvm也没安装成功,还是我最开始忘记使用user,而在安装完rvm后,ruby也用了root权限安装。不知道这里的影响会有什么,总之,我犯了一个错误,版本搭配错误。
应该是 ruby1.9.2搭配rails3.0.7。
好吧,还好有rvm,安装ruby1.9.2,再 gem install rails,竟然没有出现第一次时候的 ri 错误。欣慰吧。
这里还有一些细节,不影响整体即可,现在 rails new testrails 成功创建了一个应用。
4、安装svn
曾经熟悉的svn页面,已经转移到 apache 下,地址在这,http://subversion.apache.org/ ,用户手册在 http://svnbook.red-bean.com/ 。
按照一些文章介绍,安装svn实在太复杂了,突然我想起来yum和apt-get。来试一下。
yum install subversion
成功了。
按照这个文档,我配置过两次,这里不再详述了,又需要的朋友看一下。
我每次都会参照它ignore的操作。
5、ssh配置
在我本地重新生成一个key,其实没必要的,我只是出于练习的目的。
>> ssh-keygen -t rsa
在服务器上
>> mkdir .ssh (其实没太大必要了,因为我的key不打算放到这里了)
然后传输这个key上去
>> scp ~/.ssh/id_rsa.pub loginname@hostdomain:.ssh/authorized_keys
这里把key命名为authorized_keys。按照一些教程的说明,综合起来简单笔记一下。
在/etc/ssh/<username>建立文件夹,将authorized_keys mv进来,并给予权限
>> chmod 755 <username>
>> chmod 644 <username>/authorized_keys
编辑/etc/ssh/sshd_config,改写这一行
AuthorizedKeysFile /etc/ssh/%u/authorized_keys
并取消注释这两行
RSAAuthentication yes
PubkeyAuthentication yes
保存后,
>> /etc/init.d/sshd restart
启动另一个终端,登录时弹出一个窗口提示输入密码,其实就是刚才生成key时候的passphrase。确认后,就不用输入密码直接登录了。
这里有一个调试经验。
>> ssh -v name@domain
会输出交互信息,这里我发现它先校验key,如果不通过,就校验登录密码了。所以,如果上面的任何一个步骤有问题,比如权限不对或者写错字母,这里就会继续提示需要密码。
如果上面的都正确了,这时就不用再次输入密码直接登录了。
感谢这篇文章,让我节省了如此多的时间。感谢分享的精神。
接着需要提高一些安全性了,常见的有
PermitRootLogin no (禁止用root登录,这是默认的,当然有些时候会被其他的开发人员打开,检查一下是必要的)
StrictModes yes (也是默认的)
PasswordAuthentication no (禁用密码登录,加上这个安全性就足够了,当然还有其他,欢迎各位指点。)
时间过去了一个星期,这期间我在调试一个Rails程序,打算下面部署到服务器上,而不是随便用个railstest应付了事。这里又温习了很多rails得技巧,不过时间好快,一下子就是8天的时间。
好了,我的Rails程序已经基本完成小样了,开始用capistrano设置。
6、Capistrano
这里稍微特殊一些的地方,是我用的svn+ssh(注意顺序,写反了不行)链接服务器并cap命令。这里没有办法证明一件事情,写出来供大家参考,就是私钥设置完,在服务器上也测试一下,比如
svn checkout -q -r5 svn+ssh://domain.com/test/trunk tmp
这里会要求输入passphrase,或者添加host到know_host,都可能潜在的影响第一次cap的成功。当然,第一次cap失败可能是必然的,关键是下面分享一下我的deploy.rb给大家参考,减少一些查询的时间,当然很多东西还得看过说明才了解,建议看这篇文章,很有帮助。
下面是我的代码
(略过)
在配置svn的时候,会有不同的权限设置,比如网站目录会放到/var/www/中,我觉得这是安全性的问题,超过这个笔记的范围,就不记述了。不过这其间还是看了一些文章,后面做安全调整的时候会用上的。
补充几个命令
cap -H 查看帮助
cap -T 查看任务,-vT查看更多任务
cap -e deploy:cold 查看deploy:cold 的说明
7、apapche,nginx和passenger
因为CentOS上的apache已经安装好了,所以这里只要安装一下passenger就可以了,安装起来竟然无比简单,缺少的lib按照提示yum一下就可以了。
8、安装sqlite3-ruby的问题
google了一下发现很多人安装这个出现问题,yum install sqlite3-ruby 也不可以,这里很奇怪,yum竟然找不到这个包。
省去一些步骤,直接 yum search sqlite, 发现给出的包有:
原来是包的名称不对,所以
yum install sqlite.i386
提示已经安装
yum install sqlite-devel.i386
安装成功,再次 gem install sqlite3,提示
sqlite3-ruby only supports sqlite3 versions 3.6.16+, please upgrade!
好,可算有了进展。下载 http://www.sqlite.org/download.html 最新版本的sqlite,安装后,再次 gem install sqlite3,成功了!!
回到rails目录,再次 bundle install。胜利完成。
9、rake任务出错,/lib/rake.rb:32: warning: already initialized constant RAKEVERSION
临时的解决办法,bundle exec rake RAILS_ENV=production db:migrate
这不是最终解决办法,还在找,刚才心急一下给发布了,其实还没写完呢。。
问题发现了,是rake的问题,卸载之后重新安装rake 0.8.7,问题暂时解决。
10、No such file or directory - /tmp/mysql.sock
CentOS的位置和方法,在此备注,ln -s /var/lib/mysql/mysql.sock /tmp/mysql.sock
11、invalid packet: sequence number mismatch(3 != 1(expected))
说是ruby-mysql2.9.4的问题,暂时使用2.9.3。但是问题依旧。
gem 'mysql2', '0.2.7' 和gem 'mysql'的区别
最新版本的mysql2,是0.3.2,这是集成进rails3.1的,不适用于rails3.0.7,所以需要指定版本为0.2.7,环境可以为Raisl 3.0.x和mysql 5.x
gem 'ruby-mysql'和gem 'mysql-ruby'的区别:都不用了,直接用 gem 'mysql'
“invalid packet: sequence number mismatch”的问题已经解决,去掉ruby-mysql的gem,直接使用 gem 'mysql'
在我的版本环境里,gem 'mysql2'也不行,我的环境,rvm, ruby1.9.2p180, rails 3.0.7
12、rake 0.9.2和0.8.7,会被同时安装,也会因为0.9.2产生问题,建议删除0.9.2
13、自动执行rake任务
看了一些介绍,其实总结起来是三个事情
(1)参照系统默认的crontab任务,这方面资料很多
(2)rails的好处是gem和实现方案很多,建议使用 whenever 来实现,它会直接提示代码如何写,粘贴到当前用户的crontab里就可以
(3)具体做法,
>> crontab -e 编辑当前用户的cron任务
>> */30 * * * * /bin/bash -l -c 'cd /home/liwei/wwwroot/appflying.com && RAILS_ENV=production rake autorss:work --silent'
其实这个文件就这一行就可以,我完整的代码是
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/rvm/gems/ruby-1.9.2-p180@global/bin
MAILTO=root
HOME=/home/liwei
*/30 * * * * /bin/bash -l -c 'cd /home/liwei/wwwroot/appflying.com && RAILS_ENV=production rake autorss:work --silent'
写在最后:算是大功告成??其实我没感觉,但是总算把我想写的内容写完了。后面还会有一些笔记。这个笔记到此用了2周时间,留念。
hello, rails3.1 pre 第二部分
接着上一篇,问题继续。
rake db:migrate
>> rake aborted!
>> undefined method `task' for #<Rails31test::Application:0x00000100de6a60>
好吧,继续找答案,此处还是省略一些细节,直接看这里吧。
>> bundle exec rake db:migrate
问题暂时解决。
至此,projects已经可以看到了,剩下的还在琢磨。
补充一些链接:
CoffeeScript http://jashkenas.github.com/coffee-script/
RVM(Ruby Version Manager) https://rvm.beginrescueend.com/
SASS/SCSS http://sass-lang.com/
Sprockets http://getsprockets.org/
Hello, Rails3.1 pre
Rails3.1面世了,赶紧尝鲜吧。可是,第一个问题就出现了,更新失败。此处略过一堆字,直接笔记:安装rvm吧。
https://rvm.beginrescueend.com/rvm/install/
rvm简直是多版本ruby开发环境下的救世主。补充一下笔记:
在安装完rvm后,rails new rails31test 新建了一个测试项目,一切正常,可是bundle的时候出错,就连 gem list都出错。查了一下,原来我们要重新安装gem,也要重新装rails。
ps:各位是不是会觉得,我刚才安装了阿,为什么又要装一次?你是不是也看这个视频了?http://railscasts.com/episodes/265-rails-3-1-overview
一切都没错,只是rvm 1.9.2@railspre --create 是新建了一个gemsets,(此语法为简写)。这样我们还得安装一下bundler
rails31test liwei$ gem install bundler
rails31test liwei$ bundle
rails31test liwei$ rails g scaffold project name:string
... ...
/Users/apple/.rvm/gems/ruby-1.9.2-p180/gems/actionpack-3.1.0.beta1/lib/sprockets/railtie.rb:37:in `block (2 levels) in <class:Railtie>': undefined method `context' for #<Sprockets::Environment:0x0000010312c420> (NoMethodError)
查到这个问题的解决办法:https://github.com/rails/rails/issues/453
在Gemfile里写:
gem 'sprockets', '2.0.0.beta.2'
原因:beta.2 is required by rails 3.1.0beta1
注意:安装的时候,使用的是 gem 'sprockets', '2.0.0.beta.5',所以还要 bundle update sprockets 降回到beta.2
再次
rails31test liwei$ rails g scaffold project name:string
成功
未完待续吧... ...
redmine插件开发心得
上上周经Q友介绍,接了一个redmine插件开发的小项目。我很感兴趣的是可以借此机会把redmine熟悉一下,所以没太考虑价钱就答应了下来。现在想想,这次开发学到的东西很多,也认识了专业的开发团队,很值得。下面把redmine插件开发的经验笔记一下。
先来截图:
地址:http://www.cocos2d-x.org/projects/cocos2d-x/apps
简单介绍下
cocos2d-x is a multi-platform, light weight & developer-friendly C++ 2D mobile game engine, open source and released under MIT License. It is a child branch of the famous "cocos2d-iphone" project, and will keep the primary features sync with it.
更多细节请访问 http://www.cocos2d-x.org/projects/cocos2d-x/wiki
好了,说下这个插件实现的功能。
一是管理发布平台,比如iOS,Android,WoPhone,Windows,Other,未来它还会有其他的平台。
二是在这些平台分类里,上传app,比如时下最火的iOS app,android app等。当上传iOS app时,可自动采集该信息。
一、让我们开始
插件如何开发呢?下载其他插件的代码来研究是关键的第一步。因为之前对redmine插件开发一无所知,所以下面的笔记有点啰唆。
先看一下官方发布的插件开发文档,http://www.redmine.org/projects/redmine/wiki/Plugin_Tutorial,请大概的了解一下。然后,我们去redmine插件列表,下载两个很有代表性的插件,redmine_polls和redmine_bookmarks,把它们放到 vendor/plugins 里。选择这两个插件的原因是它们都是自主上传,填写内容的。
注意:在最新版本的redmine1.1中,polls会引起个异常。
二、如何管理插件
这是插件管理界面,如果你按照上面插件教程开发的话,你会发现缺少了Configure功能。如何加入这个功能,并且它可以做什么?可以完全的参考上面两个插件中的init.rb 和games插件里的写法。
settings :default => {},
:partial => 'platforms/manage'
这两行代码的作用,使得我们可以编辑一个页面,这个页面里,实现了games的platform管理。当然,你也可以在configure里增加apps的管理,丰富管理员功能。
这里要注意的是,权限如何分配了。
三、如何分配权限
按照文档的描述,我们可以很妥善的分配各个角色的权限。public => true,即可将所指定的action开放给所有人,如果想屏蔽掉未登录的账号访问,:require => :loggedin 即可。如果想对登录账号做区别,就需要针对每个action做以分别了。
权限设置的文档不够全,建议大家多参考别人的代码,和看源代码分析一些用法。
四、设置导航菜单
在插件的init.rb文件里,需要单独写一遍插件所使用的路由规则,为了是插件地址更没关,我们的做一些代码上的牺牲。
ActionController::Routing::Routes.draw do |map|
map.connect 'projects/:project_id/apps', :controller => "apps", :action => "index"
map.connect 'projects/:project_id/apps/all', :controller => "apps", :action => "all"
map.connect 'projects/:project_id/apps/:id', :controller => "apps", :action => "show"
map.resources :apps,
:member => {:recommend => :post, :delete_pic => :post, :snatching => :get, :doing => :post},
:collection => {:all => :get}
end
这是games里的设置,只是将三个方法做了前缀处理,这样可以和其他导航链接类似,都是 /projects/text_proj/apps/9 的形式。否则,按照resource的形式,将会是很难看(客户也不会接受的)/apps/9?project_id=text_proj
五、开发插件代码
这是我们最熟悉的部分了,此处省略一万字节。
六、使用js和css
这个地方有点麻烦,每次改动都得重启一下服务,因为每次重启才会将js代码和css文件同步到public下,当然我们可以在public下去写,收工前拿回到插件目录下,可是插件用的文件都不大,何况我都是production下开发,改哪个代码都得重启。(development下的执行速度你们是知道的)。
七、抓取app store
games插件有一个很重要的功能,就是到app store页面去采集app信息。代码在lib下的app_snatcher.rb,功能比较简单,仅做参考吧。
八、其他插件和gem
出于尝试的目的,我使用了will_paginate插件来实现分页,paperclip来保存app采集时候的icon和screenshot,在采集时使用了两个gem,请编辑你的environment.rb,增加
config.gem 'hpricot'
config.gem 'mechanize'
九、总结
如果你觉得这个代码对你开发redmine插件又帮助,可以在这里下载它:https://github.com/liwei78/redmine-games 。
欢迎和各位交个朋友,我个人的博客:http://liwei.me,目前正在设计新的界面,会把我的介绍,包括工作内容,都整理发布到上面。
十:广告一下
前者关注电子商务动态和IT业内新闻,后者为京东商城点评,购物推介点评。
Update at 2011-6-15
升级了一下,0.0.1到0.0.2,增加了lightbox显示screenshots
errors.add_to_base和errors.add
我们在页面上进行ajax校验属性的时候,有两种情况会碰到。
一种是,只要出错,就给一个提示。这个比较常见的就是“您填写的用户名或密码不正确”。因为这里可能做了三组判断,先判断用户名是否存在,然后是密码是否为空,三是两者能否检索出一条纪录。如果那个出现为空,就直接返回false,controller也就直接宣布了上面那句话。
第二种比较复杂,就是每个属性都会给一个详细的解释,甚至多个解释,比如邮件格式不正确,邮件不能为空,邮件应该以字母开头等等。因为ajax判断有时候不一定会把model实例传回来,而可能只给一个message,让view去针对该输入进行提示,比如那个经典的输入矿失去焦点时校验。
针对上面两种方法,我经常用到的就是 errors.add_to_base 和 errors.add 方法。这里做以笔记。内容来自rdoc
def validate!
errors.add(:name, "can not be nil") if name == nil
end
def validate!
errors.add_to_base("can not be nil") if name == nil
end
其实,它们是一样的
def add_to_base(msg)
add(:base, msg)
end
做以笔记,因为有时候真的会忘记这些小代码。
补充几个方法:
def Person.human_attribute_name(attr, options = {})
attr
end
它可以把名称更人性化的输出,比如“first_name” 输出为 "First name"。但是它是一个过时的方法,我们会得到一个提示:"ActiveRecord::Errors#generate_message has been deprecated. Please use ActiveRecord::Error.new().to_s."
company = Company.create(:address => '123 First St.')
company.errors.on(:name) # => ["is too short (minimum is 5 characters)", "can't be blank"]
company.errors.on(:email) # => "can't be blank"
company.errors.on(:address) # => nil
显而易见
def on_base
on(:base)
end
对上面方法的一个补充。
我喜欢netbeans的一个很重要原因就是查看这些代码的doc很方便,有时候一个简单的方法附近的doc就能读上和体会一阵子。呵呵。
其他实用的方法欢迎各位补充。
2011,让APP飞一会吧
2011,我有个惊奇的开始,我的iTouch有一天突然可以上网了,原因不明。紧接着几天,接触了一个开发项目,是做一个APP介绍的网站。可以用Rails。这一点实在让我暗地里欢喜:可算有得发挥了。接着,《让子弹飞》上映,那就让APP也跟着飞一会吧。
经过一个多月的敲敲打打,www.myappblog.net 正式上线了,这里把以往Rails2.x用过的技术,在Rails3.0平台上又加强了一遍,认真体会了一下Rails 3带来的变革。
MyAPPBlog网站是一个iPhone,iPad应用推荐,点评的网站,上面还增加了很多视频,讲解游戏的玩法,看得我实在兴奋阿。对于不经常逛app store的我来说,没事看看MyAppBlog的资讯,能发现太多不知道的事情。MyAPPBlog就像一本App杂志,很方便,而且,它是我的又一个五星级的程序作品。(哈哈)
从MyAPPBlog的网站定位上,可以看到它的特点:一是信息分享,比如最新的资讯,免费的app,二是APP操作视频,强烈建议把怒鸟的攻略发布一下,因为某人。。。。
说说程序,MyAPPBlog用了haml和sass,这极大的提高了页面的可维护性。这不是一点点的改变,而是把页面结构,设定的更加规范,比如div class的设计
.title
= @app.title
这样就实现了一个div层的结构。sass我目前用到它三个特性,变量,命名空间和继承。
Rails3让MyAPPBlog的维护更加方便,尤其是之前很难受的fckeditor的附件处理,Rails3上可用的ckeditor gem,直接用了paperclip,图片文件上传省了很多代码。
后面的工作集中在app store的数据分析上,任务挑战很大,但应用前景非常看好。
这里稍微提一下,个人对工作的定义也有了一些改进,目前的工作应该叫技术支持。
大多数人理解的外包是拿钱走人的形式,所以,技术支持,就是一个长期的服务状态,在Rails的领域里进行不断的积累,将自身的成果分享给每一个客户。
写在最后:
夜深人静,32岁的人,已经没有了当年创业时候的冲动,也没有开发搜索引擎时候的韧劲。事情按部就班的继续,看着一群比自己小10岁的年轻人,他们是不是也在经历我过去10年所做过的事情呢?我现在做的,未来做的,是不是他们10年后也要来做的呢?