<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>里克的自习室 &#187; rails</title>
	<atom:link href="http://railser.cn/blog/tag/rails/feed" rel="self" type="application/rss+xml" />
	<link>http://railser.cn</link>
	<description>关注Ruby和Rails的学习与开发</description>
	<lastBuildDate>Tue, 20 Dec 2011 11:47:47 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>在CentOS5上部署Rails3应用</title>
		<link>http://railser.cn/blog/rails-on-centos-step-by-step</link>
		<comments>http://railser.cn/blog/rails-on-centos-step-by-step#comments</comments>
		<pubDate>Mon, 06 Jun 2011 16:02:41 +0000</pubDate>
		<dc:creator>里克</dc:creator>
				<category><![CDATA[Advanced Rails]]></category>
		<category><![CDATA[RailsNote]]></category>
		<category><![CDATA[capistrano]]></category>
		<category><![CDATA[centos]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[passenger]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[rvm]]></category>
		<category><![CDATA[ssh]]></category>
		<category><![CDATA[svn]]></category>
		<category><![CDATA[whenever]]></category>

		<guid isPermaLink="false">http://railser.cn/?p=609</guid>
		<description><![CDATA[1、安装rvm 安装rvm前，要先安装git。因为rvm的安装教程就是一个git的小脚本。 &#62;&#62;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 &#124; 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 [...]]]></description>
			<content:encoded><![CDATA[<p>1、安装rvm</p>
<p>安装rvm前，要先安装git。因为rvm的安装教程就是一个git的小脚本。</p>
<p>&gt;&gt;wget http://kernel.org/pub/software/scm/git/git-1.7.5.3.tar.bz2</p>
<p>Oop！这里有个问题，我tar不常用，这里tar xvfz git-... 是会提出格式错误的，查了一下需要换一个命令：tar -xvjpf git-...</p>
<p>之后，</p>
<p>make prefix=/usr/local all</p>
<p>make prefix=/usr/local install</p>
<p>看到git 版本后，安装rvm</p>
<p>git --version</p>
<p>剩下的，就是按照 https://rvm.beginrescueend.com/rvm/install/ 的讲解一步步安装吧，最后，阿？为什么</p>
<pre>type rvm | head -1</pre>
<p>会提示错误呢？我也被搞糊涂了，按照提示，我重新打开一个终端窗口，这下正常了。所以再看看文档吧。</p>
<p>接着，安装1.8.7</p>
<p>2、安装ruby 1.8.7和gem</p>
<p>rvm install 1.8.7</p>
<p>注：我又将用户切换回了root，而在进行到Load RVM into your shell sessions as a function的时候，我不得不切换回user。</p>
<p>rvm use 1.8.7</p>
<p>显示正常了。</p>
<p>安装gems</p>
<p>http://rubygems.org/pages/download</p>
<p>3、安装rails</p>
<p>gem install rails -v 3.0.7 --no-rdoc --no-ri</p>
<p>如果安装rdoc和ri，我出现了问题，具体的情况未明。</p>
<p>问题又来了，&gt;&gt; rails -v 找不到命令</p>
<p>翻看文章的过程中，有一句话很重要，“gem install rails     # 注意不要加sudo，否则会安到系统的ruby下，而不是rvm的ruby下”</p>
<p>这是在百度里查到的，可是不用root，rvm也没安装成功，还是我最开始忘记使用user，而在安装完rvm后，ruby也用了root权限安装。不知道这里的影响会有什么，总之，我犯了一个错误，版本搭配错误。</p>
<p>应该是 ruby1.9.2搭配rails3.0.7。</p>
<p>好吧，还好有rvm，安装ruby1.9.2，再 gem install rails，竟然没有出现第一次时候的 ri 错误。欣慰吧。</p>
<p>这里还有一些细节，不影响整体即可，现在 rails new testrails 成功创建了一个应用。</p>
<p>4、安装svn</p>
<p>曾经熟悉的svn页面，已经转移到 apache 下，地址在这，http://subversion.apache.org/ ，用户手册在 http://svnbook.red-bean.com/ 。</p>
<p>按照一些文章介绍，安装svn实在太复杂了，突然我想起来yum和apt-get。来试一下。</p>
<p>yum install subversion</p>
<p>成功了。</p>
<p>按照<a href="http://www.hostingrails.com/Subversion-Rails-Implement-Your-Own-Version-Control-System" target="_blank">这个文档</a>，我配置过两次，这里不再详述了，又需要的朋友看一下。</p>
<p>我每次都会参照它ignore的操作。</p>
<p>5、<span style="color: #ff0000;">ssh配置</span></p>
<p>在我本地重新生成一个key，其实没必要的，我只是出于练习的目的。</p>
<p>&gt;&gt; ssh-keygen -t rsa</p>
<p>在服务器上</p>
<p>&gt;&gt; mkdir .ssh (其实没太大必要了，因为我的key不打算放到这里了)</p>
<p>然后传输这个key上去</p>
<p>&gt;&gt; scp ~/.ssh/id_rsa.pub loginname@hostdomain:.ssh/authorized_keys</p>
<p>这里把key命名为authorized_keys。按照一些教程的说明，综合起来简单笔记一下。</p>
<p>在/etc/ssh/&lt;username&gt;建立文件夹，将authorized_keys mv进来，并给予权限</p>
<p>&gt;&gt; chmod 755 &lt;username&gt;</p>
<p>&gt;&gt; chmod 644 &lt;username&gt;/authorized_keys</p>
<p>编辑/etc/ssh/sshd_config，改写这一行</p>
<p>AuthorizedKeysFile    /etc/ssh/%u/authorized_keys</p>
<p>并取消注释这两行</p>
<p>RSAAuthentication yes</p>
<p>PubkeyAuthentication yes</p>
<p>保存后，</p>
<p>&gt;&gt; /etc/init.d/sshd restart</p>
<p>启动另一个终端，登录时弹出一个窗口提示输入密码，其实就是刚才生成key时候的passphrase。确认后，就不用输入密码直接登录了。</p>
<p>这里有一个调试经验。</p>
<p>&gt;&gt; ssh -v name@domain</p>
<p>会输出交互信息，这里我发现它先校验key，如果不通过，就校验登录密码了。所以，如果上面的任何一个步骤有问题，比如权限不对或者写错字母，这里就会继续提示需要密码。</p>
<p>如果上面的都正确了，这时就不用再次输入密码直接登录了。</p>
<p>感谢<a href="https://help.ubuntu.com/community/SSH/OpenSSH/Keys" target="_blank">这篇文章</a>，让我节省了如此多的时间。感谢分享的精神。</p>
<p>接着需要提高一些安全性了，常见的有</p>
<p>PermitRootLogin no （禁止用root登录，这是默认的，当然有些时候会被其他的开发人员打开，检查一下是必要的）</p>
<p>StrictModes yes （也是默认的）</p>
<p>PasswordAuthentication no （禁用密码登录，加上这个安全性就足够了，当然还有其他，欢迎各位指点。）</p>
<p>&nbsp;</p>
<p>时间过去了一个星期，这期间我在调试一个Rails程序，打算下面部署到服务器上，而不是随便用个railstest应付了事。这里又温习了很多rails得技巧，不过时间好快，一下子就是8天的时间。</p>
<p>好了，我的Rails程序已经基本完成小样了，开始用capistrano设置。</p>
<p>6、Capistrano</p>
<p>这里稍微特殊一些的地方，是我用的svn+ssh（注意顺序，写反了不行）链接服务器并cap命令。这里没有办法证明一件事情，写出来供大家参考，就是私钥设置完，在服务器上也测试一下，比如</p>
<p>svn checkout -q  -r5 svn+ssh://domain.com/test/trunk tmp</p>
<p>这里会要求输入passphrase，或者添加host到know_host，都可能潜在的影响第一次cap的成功。当然，第一次cap失败可能是必然的，关键是下面分享一下我的deploy.rb给大家参考，减少一些查询的时间，当然很多东西还得看过说明才了解，建议看<a href="http://help.github.com/capistrano/" target="_blank">这篇文章</a>，很有帮助。</p>
<p>下面是我的代码</p>
<p>(略过)</p>
<p>在配置svn的时候，会有不同的权限设置，比如网站目录会放到/var/www/中，我觉得这是安全性的问题，超过这个笔记的范围，就不记述了。不过这其间还是看了一些文章，后面做安全调整的时候会用上的。</p>
<p>补充几个命令</p>
<p>cap -H 查看帮助</p>
<p>cap -T 查看任务，-vT查看更多任务</p>
<p>cap -e deploy:cold 查看deploy:cold 的说明</p>
<p>7、apapche，nginx和passenger</p>
<p>因为CentOS上的apache已经安装好了，所以这里只要安装一下passenger就可以了，安装起来竟然无比简单，缺少的lib按照提示yum一下就可以了。</p>
<p>&nbsp;</p>
<p>8、安装sqlite3-ruby的问题</p>
<p>google了一下发现很多人安装这个出现问题，yum install sqlite3-ruby 也不可以，这里很奇怪，yum竟然找不到这个包。</p>
<p>省去一些步骤，直接 yum search sqlite， 发现给出的包有：</p>
<div>
<div>
<div>mono-data-sqlite.i386 : sqlite database connectivity for Mono</div>
<div>pdns-backend-sqlite.i386 : SQLite backend for pdns</div>
<div>php-pear-Log.noarch : Abstracted logging facility for PHP</div>
<div>python-sqlite.i386 : Python bindings for sqlite.</div>
<div>qt4-sqlite.i386 : SQLite drivers for Qt's SQL classes</div>
<div>sqlite.i386 : Library that implements an embeddable SQL database engine</div>
<div>sqlite-devel.i386 : Development tools for the sqlite3 embeddable SQL database engine.</div>
</div>
</div>
<p>原来是包的名称不对，所以</p>
<p>yum install sqlite.i386</p>
<p>提示已经安装</p>
<p>yum install sqlite-devel.i386</p>
<p>安装成功，再次 gem install sqlite3，提示</p>
<p>sqlite3-ruby only supports sqlite3 versions 3.6.16+, please upgrade!</p>
<p>好，可算有了进展。下载 http://www.sqlite.org/download.html 最新版本的sqlite，安装后，再次 gem install sqlite3，成功了！！</p>
<p>回到rails目录，再次 bundle install。胜利完成。</p>
<p>9、rake任务出错，/lib/rake.rb:32: warning: already initialized constant RAKEVERSION</p>
<p>临时的解决办法，bundle exec rake RAILS_ENV=production  db:migrate</p>
<p>这不是最终解决办法，还在找，刚才心急一下给发布了，其实还没写完呢。。</p>
<p>问题发现了，是rake的问题，卸载之后重新安装rake 0.8.7，问题暂时解决。</p>
<p>10、No such file or directory - /tmp/mysql.sock</p>
<p>CentOS的位置和方法，在此备注，ln -s /var/lib/mysql/mysql.sock /tmp/mysql.sock</p>
<p>11、invalid packet: sequence number mismatch(3 != 1(expected))</p>
<p>说是ruby-mysql2.9.4的问题，暂时使用2.9.3。但是问题依旧。</p>
<p>gem 'mysql2', '0.2.7' 和gem 'mysql'的区别</p>
<p>最新版本的mysql2，是0.3.2，这是集成进rails3.1的，不适用于rails3.0.7，所以需要指定版本为0.2.7，环境可以为Raisl 3.0.x和mysql 5.x</p>
<p>gem 'ruby-mysql'和gem 'mysql-ruby'的区别：都不用了，直接用 gem 'mysql'</p>
<p>“invalid packet: sequence number mismatch”的问题已经解决，去掉ruby-mysql的gem，直接使用 gem 'mysql'</p>
<p>在我的版本环境里，gem 'mysql2'也不行，我的环境，rvm, ruby1.9.2p180, rails 3.0.7</p>
<p>12、rake 0.9.2和0.8.7，会被同时安装，也会因为0.9.2产生问题，建议删除0.9.2</p>
<p>&nbsp;</p>
<p>13、自动执行rake任务</p>
<p>看了一些介绍，其实总结起来是三个事情</p>
<p>（1）参照系统默认的crontab任务，这方面资料很多</p>
<p>（2）rails的好处是gem和实现方案很多，建议使用 <a href="https://github.com/javan/whenever" target="_blank">whenever</a> 来实现，它会直接提示代码如何写，粘贴到当前用户的crontab里就可以</p>
<p>（3）具体做法，</p>
<p>&gt;&gt; crontab -e   编辑当前用户的cron任务</p>
<p>&gt;&gt;  */30 * * * * /bin/bash -l -c 'cd /home/liwei/wwwroot/appflying.com &amp;&amp; RAILS_ENV=production rake autorss:work --silent'</p>
<p>其实这个文件就这一行就可以，我完整的代码是</p>
<p>SHELL=/bin/bash</p>
<p>PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/rvm/gems/ruby-1.9.2-p180@global/bin</p>
<p>MAILTO=root</p>
<p>HOME=/home/liwei<br />
*/30 * * * * /bin/bash -l -c 'cd /home/liwei/wwwroot/appflying.com &amp;&amp; RAILS_ENV=production rake autorss:work --silent'</p>
<p>&nbsp;</p>
<p>写在最后：算是大功告成？？其实我没感觉，但是总算把我想写的内容写完了。后面还会有一些笔记。这个笔记到此用了2周时间，留念。</p>
]]></content:encoded>
			<wfw:commentRss>http://railser.cn/blog/rails-on-centos-step-by-step/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>在mac上配制Rails开发环境</title>
		<link>http://railser.cn/blog/rails-on-mac</link>
		<comments>http://railser.cn/blog/rails-on-mac#comments</comments>
		<pubDate>Sun, 02 May 2010 06:24:36 +0000</pubDate>
		<dc:creator>里克</dc:creator>
				<category><![CDATA[apple mac]]></category>
		<category><![CDATA[mac]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://railser.cn/?p=457</guid>
		<description><![CDATA[拿到mac后最重要的就是先把Rails开发环境装好。apple介绍上写的是，mac mini装的是server版本，这样开发环境应该是已经装好的。可我的不是，没有Rails环境，只有ruby 1.8.7。这样也好，体验一下配制开发环境的过程。 1、gem 安装Rails 这个没有问题，默认已经安装了2.2.2，只要再装上需要的几个版本就可以 2、装xcode 问题来了，rake的时候出错，按照ubuntu的经验，估计是缺少编译环境，ubuntu上是装了ruby－dev。 装上xcode，问题解决。（本人绝对新人，欢迎朋友们指教，更多资料大家google吧） 3、装MacPort 这是一个奇怪的感觉，没有apt-get感觉不太习惯，所以装上MacPort，继续装ImageMagick，这个竟然用了一个多小时，具体安装方法参考：http://rmagick.rubyforge.org/install-osx.html 4、重点来了，mysql，apache，php环境 其实本想一个个装一下，但是看到了mamp，就试验一下，没想到很容易就搞定了。。 参考： http://www.mamp.info/en/downloads/index.html 可是，问题没结束，gem install mysql的时候出现了问题，因为mysql是俗话讲的集成，免安装过来的，不是默认配制，所以，需要重新编译一下mamp的mysql部分，才能正常gem安装mysql驱动。 重点在：gem install -v=2.7 mysql -- --with-mysql-config=/Applications/MAMP/Library/bin/mysql_config 注意红色的部分，因为最新的2.8.1会提示“Virtual timer expired”。建议大家不要轻易升级gem，实在要升级，一定本地环境完全模拟一遍，包括各个gem版本，建议用rvm的朋友一定要多留意，rvm很好，一定要早入手熟悉。 具体参考：http://boonedocks.net/mike/archives/175-MAMP-and-the-Ruby-MySQL-Gem.html 进行到这里感觉很幸福，发现分享自己的经验原来可以帮人解决那么多问题，也节省时间。这也是我写这个笔记，分享经历的动力。 5、终于到textmate了 macx.cn的软件栏目里有下载，总算见到textmate的样子了，之前netbeans也只是模仿一点点样子而已。 更多的textmate使用见仁见智吧，不多说，目前很痴迷mac，好玩的东西都要用一下。 写到这，环境基本ok了，开始Rails的工作吧。]]></description>
			<content:encoded><![CDATA[<p>拿到mac后最重要的就是先把Rails开发环境装好。apple介绍上写的是，mac mini装的是server版本，这样开发环境应该是已经装好的。可我的不是，没有Rails环境，只有ruby 1.8.7。这样也好，体验一下配制开发环境的过程。</p>
<p>1、gem 安装Rails</p>
<p>这个没有问题，默认已经安装了2.2.2，只要再装上需要的几个版本就可以</p>
<p>2、装xcode</p>
<p>问题来了，rake的时候出错，按照ubuntu的经验，估计是缺少编译环境，ubuntu上是装了ruby－dev。</p>
<p>装上xcode，问题解决。（本人绝对新人，欢迎朋友们指教，更多资料大家google吧）</p>
<p>3、装MacPort</p>
<p>这是一个奇怪的感觉，没有apt-get感觉不太习惯，所以装上MacPort，继续装ImageMagick，这个竟然用了一个多小时，具体安装方法参考：<a href="http://rmagick.rubyforge.org/install-osx.html">http://rmagick.rubyforge.org/install-osx.html</a></p>
<p>4、重点来了，mysql，apache，php环境</p>
<p>其实本想一个个装一下，但是看到了mamp，就试验一下，没想到很容易就搞定了。。</p>
<p>参考： <a href="http://www.mamp.info/en/downloads/index.html">http://www.mamp.info/en/downloads/index.html</a></p>
<p>可是，问题没结束，gem install mysql的时候出现了问题，因为mysql是俗话讲的集成，免安装过来的，不是默认配制，所以，需要重新编译一下mamp的mysql部分，才能正常gem安装mysql驱动。</p>
<p>重点在：gem install<span style="color: #ff0000;"> -v=2.7</span> mysql -- --with-mysql-config=/Applications/MAMP/Library/bin/mysql_config</p>
<p>注意红色的部分，因为最新的2.8.1会提示“Virtual timer expired”。建议大家不要轻易升级gem，实在要升级，一定本地环境完全模拟一遍，包括各个gem版本，建议用rvm的朋友一定要多留意，rvm很好，一定要早入手熟悉。</p>
<p>具体参考：<a href="http://boonedocks.net/mike/archives/175-MAMP-and-the-Ruby-MySQL-Gem.html">http://boonedocks.net/mike/archives/175-MAMP-and-the-Ruby-MySQL-Gem.html</a></p>
<p>进行到这里感觉很幸福，发现分享自己的经验原来可以帮人解决那么多问题，也节省时间。这也是我写这个笔记，分享经历的动力。</p>
<p>5、终于到textmate了</p>
<p>macx.cn的软件栏目里有下载，总算见到textmate的样子了，之前netbeans也只是模仿一点点样子而已。</p>
<p>更多的textmate使用见仁见智吧，不多说，目前很痴迷mac，好玩的东西都要用一下。</p>
<p>写到这，环境基本ok了，开始Rails的工作吧。</p>
]]></content:encoded>
			<wfw:commentRss>http://railser.cn/blog/rails-on-mac/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Rails中基于属性的动态查询</title>
		<link>http://railser.cn/blog/dynamic-attribute-based-finders</link>
		<comments>http://railser.cn/blog/dynamic-attribute-based-finders#comments</comments>
		<pubDate>Sun, 07 Dec 2008 02:26:43 +0000</pubDate>
		<dc:creator>里克</dc:creator>
				<category><![CDATA[RailsNote]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://railser.cn/?p=397</guid>
		<description><![CDATA[这是个很简单的Rails2.1.2的 find 的应用，来自Rdoc ActiveRecord::Base 一、find :first 和find :all 使用 Model.find_by_user_name ，来简写 Model.find(:first, :conditions=&#62;["user_name=?",user_name]) 使用 Model.find_all_by_user_name ，来简写 Model.find(:all, :conditions=&#62;["user_name=?",user_name]) 这里也可以使用and，比如典型的用户名和密码查询：Person.find_by_user_name_and_password(user_name, password) find也支持带参数的查询，比如Payment.find_all_by_amount(50, :order =&#62; "created_on") 二、find_or_create_by_和find_or_initialize_ find_or_create_by_：当查询的内容不存在时，创建并保存该记录 find_or_initialize_：更上面的相似，只是创建不保存该记录，需要自己再次save 这里也支持参数和代码块，如 User.find_or_create_by_name('Bob', :age =&#62; 40) { &#124;u&#124; u.admin = true } 三、find_by_的时候，支持多属性，如 Tag.find_or_create_by_name(:name =&#62; "rails", :creator =&#62; current_user) 以上文字来自Rails2.1.2的Rdoc文档ActiveRecord::Base]]></description>
			<content:encoded><![CDATA[<p>这是个很简单的Rails2.1.2的 find 的应用，来自Rdoc ActiveRecord::Base</p>
<p>一、find :first 和find :all</p>
<p>使用 Model.<span style="color: #ff0000;">find</span>_by_user_name ，来简写 Model.find(:first, :conditions=&gt;["user_name=?",user_name])</p>
<p>使用 Model.<span style="color: #ff0000;">find_all</span>_by_user_name ，来简写 Model.find(:all, :conditions=&gt;["user_name=?",user_name])</p>
<p>这里也可以使用and，比如典型的用户名和密码查询：Person.find_by_user_name_and_password(user_name, password)</p>
<p>find也支持带参数的查询，比如Payment.find_all_by_amount(50, :order =&gt; "created_on")</p>
<p>二、<span style="font-family: Courier New;">find_or_create_by_和find_or_initialize_</span></p>
<p><span style="font-family: Courier New;">find_or_create_by_：当查询的内容不存在时，<span style="color: #0000ff;">创建并保存</span>该记录</span></p>
<p><span style="font-family: Courier New;">find_or_initialize_：更上面的相似，只是<span style="color: #0000ff;">创建不保存</span><span style="color: #000000;">该记录，需要自己再次save</span></span></p>
<p><span style="font-family: Courier New;">这里也支持参数和代码块，如</span></p>
<p>User.find_or_create_by_name('Bob', :age =&gt; 40) { |u| u.admin = true }</p>
<p>三、find_by_的时候，支持多属性，如</p>
<p>Tag.find_or_create_by_name(:name =&gt; "rails", :creator =&gt; current_user)</p>
<p>以上文字来自Rails2.1.2的Rdoc文档ActiveRecord::Base</p>
]]></content:encoded>
			<wfw:commentRss>http://railser.cn/blog/dynamic-attribute-based-finders/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ruby for rails 摘录</title>
		<link>http://railser.cn/blog/ruby-for-rails-4</link>
		<comments>http://railser.cn/blog/ruby-for-rails-4#comments</comments>
		<pubDate>Mon, 17 Nov 2008 07:02:05 +0000</pubDate>
		<dc:creator>2013</dc:creator>
				<category><![CDATA[RailsNote]]></category>
		<category><![CDATA[r4r]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://railser.cn/?p=336</guid>
		<description><![CDATA[class, module, def 标志着切换到新的 self， main 是默认的 self 对象用来引用自己的专门术语。self 作为消息默认的接受者，如果消息接受者是 self ，可以省略接受者和圆点。 如果存在同名的方法名和变量，而且你使用裸词标识符，那么变量具有优先权。要强制 Ruby 将标识符当作方法名，你必须使用 self.talk 或者用参数列表为空的 talk() 来调用方法。 有一个场合，即使是发送消息给当前的 self，也必须使用完整的“对象 圆点 消息”记法，那就是在调用写方法的时候。因为 Ruby 总之将序列“裸词＝值”解释为对局部变量的赋值。为了调用当前对象的 venue= 方法，必须显示的给出 self。 private 和 protected 的区别 私有方法意味着该方法不能使用显式的接收者来调用。Ruby 认为你想要发送消息给当前对象 self。所以仅当 self 是一个可以响应消息的对象时，该消息才有对象接收。那啥时候 self 才会是类的实例呢？当执行类的任何一个实例方法时。所以看如下代码 class Baker def bake_cake @batter = [] pour_flour add_egg return Cake.new end def pour_flour @batter.push(Flour.new) end [...]]]></description>
			<content:encoded><![CDATA[<p>class, module, def 标志着切换到新的 self， main 是默认的 self 对象用来引用自己的专门术语。self 作为消息默认的接受者，如果消息接受者是 self ，可以省略接受者和圆点。</p>
<p>如果存在同名的方法名和变量，而且你使用裸词标识符，那么变量具有优先权。要强制 Ruby 将标识符当作方法名，你必须使用 self.talk 或者用参数列表为空的 talk() 来调用方法。</p>
<p>有一个场合，即使是发送消息给当前的 self，也必须使用完整的“对象 圆点 消息”记法，那就是在调用写方法的时候。因为 Ruby 总之将序列“裸词＝值”解释为对局部变量的赋值。为了调用当前对象的 venue= 方法，必须显示的给出 self。</p>
<p>private 和 protected 的区别<br />
私有方法意味着该方法不能使用显式的接收者来调用。Ruby 认为你想要发送消息给当前对象 self。所以仅当 self 是一个可以响应消息的对象时，该消息才有对象接收。那啥时候 self 才会是类的实例呢？当执行类的任何一个实例方法时。所以看如下代码</p>
<pre name="code" class="ruby">
class Baker
  def bake_cake
    @batter = []
    pour_flour
    add_egg
    return Cake.new
  end

  def pour_flour
    @batter.push(Flour.new)
  end

  def add_egg
    @batter.push(Egg.new)
  end

  private :pour_flour, :add_egg
end
</pre>
<p>总结，当 add_egg 标记为私有的，就是说Baker的实例对象可以将此消息发送给它自己，但是其它任何对象都不可以给该Baker实例对象发送该消息。Ruby 通过禁止对私有方法使用显示的接收者来获得此私有性。</p>
<p>保护方法的规则是：只要默认对象 self 和你想要调用的方法所属的对象是同一个类的实例，你就可以调用该保护方法。如果某个对象调用其所属的保护方法，而该对象所属的类和self所属的类相同，那么该调用是合法的。</p>
<pre name="code" class="ruby">
class C
  def initialize(n)
    @n = n
  end

  def n
    @n
  end

  def compare(c)
    if c.n > n
      puts "The other object's n is bigger."
    else
      puts "The other object's n is the same or smaller"
    end
  end

  protected :n
end

c1 = C.new(100)
c2 = C.new(201)
c1.compare(c2)
</pre>
]]></content:encoded>
			<wfw:commentRss>http://railser.cn/blog/ruby-for-rails-4/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ruby for rails 摘录</title>
		<link>http://railser.cn/blog/ruby-for-rails-3</link>
		<comments>http://railser.cn/blog/ruby-for-rails-3#comments</comments>
		<pubDate>Sun, 16 Nov 2008 09:06:23 +0000</pubDate>
		<dc:creator>2013</dc:creator>
				<category><![CDATA[RailsNote]]></category>
		<category><![CDATA[r4r]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://railser.cn/?p=325</guid>
		<description><![CDATA[模块没有实例，模块被混含在类中。这样类的实例可以调用定义在模块中的实例方法。混含操作由 include 语句实现。require 或 load 时，加载的内容放在引号里。但是使用 include 时，不使用引号。 module Stacklike attr_reader :stack def initialize @stack = Array.new end def add_to_stack(obj) @stack.push(obj) end def take_from_stack @stack.pop end end require "stacklike" class CargoHold include Stacklike def load_and_report(obj) pust obj.object_id add_to_stack(obj) end def unload take_from_stack end end 使用名称作为类名，使用形容词作为模块的名。上面的例子演示了如何进一步发挥模块的作用。 当给对象发送它不理解的消息的时候，会触发内建方法 method_missing 调用。 class Bicycle attr_reader :gears, :wheels, :seats def [...]]]></description>
			<content:encoded><![CDATA[<p>模块没有实例，模块被混含在类中。这样类的实例可以调用定义在模块中的实例方法。混含操作由 include 语句实现。require 或 load 时，加载的内容放在引号里。但是使用 include 时，不使用引号。</p>
<pre name="code" class="ruby">
module Stacklike
  attr_reader :stack

  def initialize
    @stack = Array.new
  end

  def add_to_stack(obj)
    @stack.push(obj)
  end

  def take_from_stack
    @stack.pop
  end
end
</pre>
<pre name="code" class="ruby">
require "stacklike"
class CargoHold
  include Stacklike

  def load_and_report(obj)
    pust obj.object_id
    add_to_stack(obj)
  end

  def unload
    take_from_stack
  end
end
</pre>
<p>使用名称作为类名，使用形容词作为模块的名。上面的例子演示了如何进一步发挥模块的作用。</p>
<p>当给对象发送它不理解的消息的时候，会触发内建方法 method_missing 调用。</p>
<pre name="code" class="ruby">
class Bicycle
  attr_reader :gears, :wheels, :seats

  def initialize(gears = 1)
    @wheels = 2
    @seats = 1
    @gears = gears
  end
end

class Tandem < Bicycle
  def initialize(gears)
    super
    @seats = 2
  end
end
</pre>
<p>以super提升方法查找路径。以裸词的方式调用时，自动向前传递调用 super 的发给你发所获得的参数。这个是默认滴。用空参数表调用 super() 时，不给上一级方法传递任何参数，即使是当前方法的谙熟也不传递。用特定参数 super(a, b, c) 时，传递这些指定的参数。</p>
]]></content:encoded>
			<wfw:commentRss>http://railser.cn/blog/ruby-for-rails-3/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ruby for rails 摘录</title>
		<link>http://railser.cn/blog/ruby-for-rails-2</link>
		<comments>http://railser.cn/blog/ruby-for-rails-2#comments</comments>
		<pubDate>Sun, 16 Nov 2008 05:37:35 +0000</pubDate>
		<dc:creator>2013</dc:creator>
				<category><![CDATA[RailsNote]]></category>
		<category><![CDATA[r4r]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://railser.cn/?p=319</guid>
		<description><![CDATA[实例变量使得单个对象可以记忆状态。实例变量的名字以@开头。实例变量仅仅对于它所属的对象来说是可见的。在一个特定类的某一方法中初始化的实例变量，与同一个类的其他方法定义中引用的同名实例变量是同一个。 class c def inst_var_init(value) puts "Setting an instance variable..." @ivar = value end def inst_var_report puts "Inspection the value of the instance variable..." puts @ivar end end 初始化对象状态 class c def initialize(venue, date) @venue = venue @date = date end def venue @venue end def date @date end end =号方法和语法糖衣，Ruby允许定义以等号结束的方法。另外当解释器看到一个裸词后面有等号的时候。它会自动忽略等号前面的空格。从而得到一条单独的消息，例如 price= 。 class Ticket [...]]]></description>
			<content:encoded><![CDATA[<p>实例变量使得单个对象可以记忆状态。实例变量的名字以@开头。实例变量仅仅对于它所属的对象来说是可见的。在一个特定类的某一方法中初始化的实例变量，与同一个类的其他方法定义中引用的同名实例变量是同一个。</p>
<pre name="code" class="ruby">
class c
  def inst_var_init(value)
    puts "Setting an instance variable..."
    @ivar = value
  end

  def inst_var_report
    puts "Inspection the value of the instance variable..."
    puts @ivar
  end
end
</pre>
<p>初始化对象状态</p>
<pre name="code" class="ruby">
class c
  def initialize(venue, date)
    @venue = venue
    @date = date
  end

  def venue
    @venue
  end

  def date
    @date
  end
end
</pre>
<p>=号方法和语法糖衣，Ruby允许定义以等号结束的方法。另外当解释器看到一个裸词后面有等号的时候。它会自动忽略等号前面的空格。从而得到一条单独的消息，例如 price= 。</p>
<pre name="code" class="ruby">
class Ticket
  def price=(amount)
    @price = amount
  end

  def price
    @price
  end
end
</pre>
<p>字符串内建的split方法的示例</p>
<pre name="code" class="ruby">
month, day, year = date.split('/')
</pre>
<p>ActiveRecord自动生成与数据库表的字段名相对应的设置方法。通过 params 方法，ActiveRecord 收集了所有属于 customer 的值， 并将它们成批地传递到新生成的 Customer 对象中。</p>
<pre name="code" class="ruby">
customer = Customer.new(params[:customer])
</pre>
<p>自动生成属性方法，attr_accessor, attr_reader, attr_writer</p>
<p>常量的名字是以一个大写字母开头。可以在类外引用常量，Ticker::VENUES</p>
<pre name="code" class="ruby">
class Ticket
  VENUES = ["Convention Center", "Fairgrounds", "Town Hall"]
end
</pre>
<p>每个类有自己的实例方法，可以继承链上面的类的实例方法。定义一个动作，就是给控制器类添加一个实例方法。</p>
]]></content:encoded>
			<wfw:commentRss>http://railser.cn/blog/ruby-for-rails-2/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ruby for rails 摘录</title>
		<link>http://railser.cn/blog/ruby-for-rails-1</link>
		<comments>http://railser.cn/blog/ruby-for-rails-1#comments</comments>
		<pubDate>Mon, 10 Nov 2008 07:19:54 +0000</pubDate>
		<dc:creator>2013</dc:creator>
				<category><![CDATA[RailsNote]]></category>
		<category><![CDATA[r4r]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://railser.cn/?p=304</guid>
		<description><![CDATA[def all @order = params[:order] &#124;&#124; "number" sort_proc = case @order when "author" then lambda {&#124;r&#124; [r.user.name.downcase, r.number]} when "status", "title", then lambda {&#124;r&#124; [r.send(@order).downcase, r.number]} when "number" then lambda {&#124;r&#124; -r.number} end @rcrs = Rcr.find(:all).sort_by &#038;sort_proc end 下面是一个 respond_to? 和 send 方法的例子 request = gets.chomp if ticket.respond_to?(request) puts ticket.send(request) else puts "No such information [...]]]></description>
			<content:encoded><![CDATA[<pre name="code" class="ruby">
def all
  @order = params[:order] || "number"
  sort_proc = case @order
    when "author" then lambda {|r| [r.user.name.downcase, r.number]}
    when "status",
             "title", then lambda {|r| [r.send(@order).downcase, r.number]}
    when "number" then lambda {|r| -r.number}
  end
  @rcrs = Rcr.find(:all).sort_by &sort_proc
end
</pre>
<p>下面是一个 respond_to? 和 send 方法的例子</p>
<pre name="code" class="ruby">
request = gets.chomp

if ticket.respond_to?(request)
  puts ticket.send(request)
else
  puts "No such information available"
end
</pre>
<p>参数的默认值</p>
<pre name="code" class="ruby">
def m(a, b=1, *m)
end

m(1,2,3,4)

a = 1, b = 1, m = [3, 4]
</pre>
]]></content:encoded>
			<wfw:commentRss>http://railser.cn/blog/ruby-for-rails-1/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>1.3.2 生成式编程：在运行中编写代码</title>
		<link>http://railser.cn/blog/generative-programming-writing-code-on-the-fly</link>
		<comments>http://railser.cn/blog/generative-programming-writing-code-on-the-fly#comments</comments>
		<pubDate>Mon, 27 Oct 2008 00:55:45 +0000</pubDate>
		<dc:creator>2013</dc:creator>
				<category><![CDATA[Advanced Rails]]></category>
		<category><![CDATA[default]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://railser.cn/?p=223</guid>
		<description><![CDATA[生成式编程（Generative Programming）——即用代码来编写代码，是一个包含了若干种技术的一种强大的技术。这种技术可以以最简单的方式实现，例如编写一段用于自动完成编程中一些单调乏味的操作的shell脚本。举个例子，假设你想为每个用户生成一个示例项目的测试fixture： brad_project: id: 1 owner_id: 1 billing_status_id: 12 john_project: id: 2 owner_id: 2 billing_status_id: 4 ... 如果这种语言不支持可脚本化（可编程）的测试fixture，你恐怕不得不手工编写了。当数据持续增加时这将会变得混乱，而且当这些测试fixture和源数据层有着奇怪的依赖关系的时候手工编写几乎变得不可能。 朴素的生成式编程能够让你编写脚本来从源数据生成这些测试fixture。虽然还不够理想，但是比起全部手工编写已经算是个巨大的进步了。但其维护仍然让人头痛，因为你不得不将那个脚本放在编译过程中，而且需要保证源数据发生了变化时测试fixture被重新生成了。 令人欣慰的是在Ruby或Rails中，这种烦恼几乎是不需要的。几乎每个方面的Rails应用的配置都是可脚本化的，这主要归因于使用了内部的特定领域语言（DSL)。在一个内部的DSL中，你能够支配使用Ruby语言的所有特性，而不仅仅是库文件作者决定要提供给你的那些特定接口。 再返回去看前面的例子，ERb将这个过程变得异常简单。我们可以通过使用ERb的&#60;% %&#62;和&#60;%= %&#62;标签在上面用到的YAML文件中插入任意的Ruby代码，包括我们需要的任何逻辑： < % User.find_all_by_active(true).each_with_index do &#124;user, i&#124; %> < %= user.login %>_project: id: < %= i %> owner_id: < %= user.id %> billing_status_id: < %= user.billing_status.id %> < % end %> ActiveReacord中对这个功能的实现几乎不能再简单了： yaml [...]]]></description>
			<content:encoded><![CDATA[<p>生成式编程（Generative Programming）——即用代码来编写代码，是一个包含了若干种技术的一种强大的技术。这种技术可以以最简单的方式实现，例如编写一段用于自动完成编程中一些单调乏味的操作的shell脚本。举个例子，假设你想为每个用户生成一个示例项目的测试fixture：</p>
<pre name="code" class="ruby">
brad_project:
  id: 1
  owner_id: 1
  billing_status_id: 12
john_project:
  id: 2
  owner_id: 2
  billing_status_id: 4
...
</pre>
<p>如果这种语言不支持可脚本化（可编程）的测试fixture，你恐怕不得不手工编写了。当数据持续增加时这将会变得混乱，而且当这些测试fixture和源数据层有着奇怪的依赖关系的时候手工编写几乎变得不可能。</p>
<p>朴素的生成式编程能够让你编写脚本来从源数据生成这些测试fixture。虽然还不够理想，但是比起全部手工编写已经算是个巨大的进步了。但其维护仍然让人头痛，因为你不得不将那个脚本放在编译过程中，而且需要保证源数据发生了变化时测试fixture被重新生成了。</p>
<p>令人欣慰的是在Ruby或Rails中，这种烦恼几乎是不需要的。几乎每个方面的Rails应用的配置都是可脚本化的，这主要归因于使用了内部的特定领域语言（DSL)。在一个内部的DSL中，你能够支配使用Ruby语言的所有特性，而不仅仅是库文件作者决定要提供给你的那些特定接口。</p>
<p>再返回去看前面的例子，ERb将这个过程变得异常简单。我们可以通过使用ERb的&lt;% %&gt;和&lt;%= %&gt;标签在上面用到的YAML文件中插入任意的Ruby代码，包括我们需要的任何逻辑：</p>
<pre name="code" class="ruby">
< % User.find_all_by_active(true).each_with_index do |user, i| %>
< %= user.login %>_project:
  id: < %= i %>
  owner_id: < %= user.id %>
  billing_status_id: < %= user.billing_status.id %>
< % end %>
</pre>
<p>ActiveReacord中对这个功能的实现几乎不能再简单了：</p>
<pre name="code" class="ruby">
yaml = YAML::load(erb_render(yaml_string))
</pre>
<p>使用了helper方法erb_render:</p>
<pre name="code" class="ruby">
def erb_render(fixture_content)
  ERB.new(fixture_content).result
end
</pre>
]]></content:encoded>
			<wfw:commentRss>http://railser.cn/blog/generative-programming-writing-code-on-the-fly/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>代码块转换为过程和过程转换为代码块</title>
		<link>http://railser.cn/blog/blocks-to-procs-and-procs-to-blocks</link>
		<comments>http://railser.cn/blog/blocks-to-procs-and-procs-to-blocks#comments</comments>
		<pubDate>Mon, 27 Oct 2008 00:27:09 +0000</pubDate>
		<dc:creator>2013</dc:creator>
				<category><![CDATA[Advanced Rails]]></category>
		<category><![CDATA[default]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://railser.cn/?p=211</guid>
		<description><![CDATA[当前的Ruby实现有一点不足：Blocks代码块不总是Procs过程，Procs过程也不总是Blocks代码块。普通的代码块（定义在do…end 或者{}中）必须依附在一个方法调用上，而不能自动成为对象。例如，你不能把代码写成code_block = {puts “abc”}。这就是Kernel#lambda 和Proce.new 的用途：将代码块转换为过程。 block_1 = lambda { puts "abc" } # => #&#60;Proc:0x00024914@-:20> block_2 = Proc.new { puts "abc" } # => #&#60;Proc:0x000246a8@-:21> Kernal#lambda与Proc.new之间仅存在着些许区别。由Kernel#lambda 创建的Proc被调用时返回给调用方法的值是在Proc中给定的值；而由Proc.new 创建的Proc被调用的时候，Proc将试图从当前的函数方法中返回，但是，如果不能从方法调用中返回那么它就抛出LocalJumpError错误。下面是一个具体的例子： def block_test lambda_proc = lambda { return 3 } proc_new_proc = Proc.new { return 4 } lambda_proc.call # => 3 proc_new_proc.call # => puts "Never [...]]]></description>
			<content:encoded><![CDATA[<p>当前的Ruby实现有一点不足：Blocks代码块不总是Procs过程，Procs过程也不总是Blocks代码块。普通的代码块（定义在do…end 或者{}中）必须依附在一个方法调用上，而不能自动成为对象。例如，你不能把代码写成code_block = {puts “abc”}。这就是Kernel#lambda 和Proce.new 的用途：将代码块转换为过程。</p>
<pre name="code" class="ruby">
block_1 = lambda { puts "abc" } # => #&lt;Proc:0x00024914@-:20>
block_2 = Proc.new { puts "abc" } # => #&lt;Proc:0x000246a8@-:21>
</pre>
<p>Kernal#lambda与Proc.new之间仅存在着些许区别。由Kernel#lambda 创建的Proc被调用时返回给调用方法的值是在Proc中给定的值；而由Proc.new 创建的Proc被调用的时候，Proc将试图从当前的函数方法中返回，但是，如果不能从方法调用中返回那么它就抛出LocalJumpError错误。下面是一个具体的例子：</p>
<pre name="code" class="ruby">
def block_test
  lambda_proc = lambda { return 3 }
  proc_new_proc = Proc.new { return 4 }
  lambda_proc.call # => 3
  proc_new_proc.call # =>
  puts "Never reached"
end
block_test # => 4
</pre>
<p>lambda_proc 中的返回语句从lambda中返回3。相反地，proc_new中的返回语句是从函数方法返回，因此——block_test，其返回的值是4。那个puts 语句将永远不能被执行到，因为proc_new_proc.call 语句首先从block_test返回。</p>
<p>通过将块传给一个方法，也能将其转换为过程，与常规的参数传递有所不同的是需要在其前面加上一个&符：</p>
<pre name="code" class="ruby">
def some_function(&b)
  puts "Block is a #{b} and returns #{b.call}"
end

some_function { 6 + 3 }
# >> Block is a #&lt;Proc:0x00025774@-:7> and returns 9
</pre>
<p>相反的，可以将前面加了&符的过程传递给一个需要块作参数的方法：</p>
<pre name="code" class="ruby">
add_3 = lambda {|x| x+3}
(1..5).map(&add_3) # => [4, 5, 6, 7, 8]
</pre>
]]></content:encoded>
			<wfw:commentRss>http://railser.cn/blog/blocks-to-procs-and-procs-to-blocks/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Method Missing</title>
		<link>http://railser.cn/blog/method-missing</link>
		<comments>http://railser.cn/blog/method-missing#comments</comments>
		<pubDate>Fri, 24 Oct 2008 06:18:00 +0000</pubDate>
		<dc:creator>2013</dc:creator>
				<category><![CDATA[Advanced Rails]]></category>
		<category><![CDATA[default]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://railser.cn/?p=176</guid>
		<description><![CDATA[解决了前几篇所有的疑惑后，理解method_missing就变得非常简单。其准则是：如果整个方法查找过程中，直到到达了Object都以失败而告终，那么将再次执行方法查找，但这次查找的是method_missing方法而不是原来调用的方法。如果method_missing方法被找到，它将被传入原方法的调用参数并调用，原调用的代码块也会被传入method_missing方法。 Object中的缺省method_missing（rb_method_missing）函数将抛出一个异常。]]></description>
			<content:encoded><![CDATA[<p>解决了前几篇所有的疑惑后，理解method_missing就变得非常简单。其准则是：如果整个方法查找过程中，直到到达了Object都以失败而告终，那么将再次执行方法查找，但这次查找的是method_missing方法而不是原来调用的方法。如果method_missing方法被找到，它将被传入原方法的调用参数并调用，原调用的代码块也会被传入method_missing方法。</p>
<p>Object中的缺省method_missing（rb_method_missing）函数将抛出一个异常。</p>
]]></content:encoded>
			<wfw:commentRss>http://railser.cn/blog/method-missing/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

