<?xml version="1.0" encoding="UTF-8"?>
  <feed xmlns="http://www.w3.org/2005/Atom">
  <title type="html"><![CDATA[Wayne's Tech Blog]]></title>
  <subtitle type="html"><![CDATA[关注Coldfusion、Oracle以及各种网络技术]]></subtitle>
  <id>http://blog.waynedeng.com/</id> 
  <link rel="alternate" type="text/html" href="http://blog.waynedeng.com/" /> 
  <link rel="self" type="application/atom+xml" href="http://blog.waynedeng.com/atom.asp" /> 
  <generator uri="http://www.pjhome.net/" version="2.4.1022">PJBlog2</generator> 
  <updated>2007-12-06T15:36:09+08:00</updated> 

  <entry>
	  <title type="html"><![CDATA[查看哪些用户在线(通过session_id获取session信息)]]></title>
	  <author>
		 <name>wayne_deng</name>
		 <uri>http://blog.waynedeng.com/</uri>
		 <email>wayne.deng.cn@gmail.com</email>
	  </author>
	  <category term="" scheme="http://blog.waynedeng.com/default.asp?cateID=47" label="ROR" /> 
	  <updated>2007-12-06T15:36:09+08:00</updated>
	  <published>2007-12-06T15:36:09+08:00</published>
		  <summary type="html"><![CDATA[一个非常有用的功能，在application全局的角度获取不同用户的session信息<br/><br/><div class="UBBPanel"><div class="UBBTitle"><img src="http://blog.waynedeng.com/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>@user=CGI::Session::ActiveRecordStore::Session.find_by_session_id(@session_id).data[:user] <br/></div></div><br/><br/><a href="http://webonrails.com/2006/12/08/accessing-session-data-using-session_id/" target="_blank">http://webonrails.com/2006/12/08/accessing-session-data-using-session_id/</a><br/><br/>看看那些用户在线<br/><div class="UBBPanel"><div class="UBBTitle"><img src="http://blog.waynedeng.com/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>def who_is_online<br/>&nbsp;&nbsp;@whos_online = Array.new()<br/>&nbsp;&nbsp;onlines = CGI::Session::ActiveRecordStore::Session.find( :all, :conditions =&gt; [ &#39;up&#100;ated_at = ?&#39;,&nbsp;&nbsp;Time.now() - 10.minutes ] )<br/>&nbsp;&nbsp;onlines.each do |online|<br/>&nbsp;&nbsp;&nbsp;&nbsp;id = Marshal.load( Base64.decode64( online.data ) )<br/>&nbsp;&nbsp;&nbsp;&nbsp;@whos_online &lt;&lt; id[ :member_id ]<br/>&nbsp;&nbsp;end<br/>&nbsp;&nbsp;return @whos_online<br/>end<br/></div></div><br/><br/><a href="http://matt-beedle.com/2006/12/13/rails-how-to-find-out-who-is-online/" target="_blank">http://matt-beedle.com/2006/12/13/rails-how-to-find-out-who-is-online/</a>]]></summary>
	  <link rel="alternate" type="text/html" href="http://blog.waynedeng.com/default.asp?id=629" /> 
	  <id>http://blog.waynedeng.com/default.asp?id=629</id> 
  </entry>	
		
  <entry>
	  <title type="html"><![CDATA[Rails中的application全局变量]]></title>
	  <author>
		 <name>wayne_deng</name>
		 <uri>http://blog.waynedeng.com/</uri>
		 <email>wayne.deng.cn@gmail.com</email>
	  </author>
	  <category term="" scheme="http://blog.waynedeng.com/default.asp?cateID=47" label="ROR" /> 
	  <updated>2007-08-04T22:33:26+08:00</updated>
	  <published>2007-08-04T22:33:26+08:00</published>
		  <summary type="html"><![CDATA[Rails中没有提供类似于coldfusion中的application全局变量。我在google中搜索，发现有人也遇到了同样的需求，如何创建一个变量从rails开始运行时初始化，一直维持到rails终止，而且对于每一个request都能共享的变量？<br/>其实实现起来很简单，因为rails使用的是ruby，我们在environment.rb里面定义一个ruby中的全局变量即可，例如$application（在ruby里面，以$开头的变量即自动申明为全局变量）。<br/>在rails启动的时候，执行在environment.rb，初始化$application，这样$application即可持续使用了。<br/>我们可以做个测试。<br/>在environment.rb最后添加：<br/>$application = 0<br/><br/>然后在testController里面：<br/>def index<br/>&nbsp;&nbsp;&nbsp;&nbsp; $application += 1<br/>end<br/><br/>index.rhtml里面：<br/>&lt;%= $application %&gt;<br/><br/>不停的刷新，就会发现数字不断增加。<br/>换一台电脑也是如此（另外一个session）。]]></summary>
	  <link rel="alternate" type="text/html" href="http://blog.waynedeng.com/default.asp?id=628" /> 
	  <id>http://blog.waynedeng.com/default.asp?id=628</id> 
  </entry>	
		
  <entry>
	  <title type="html"><![CDATA[Rails防止SQL注入]]></title>
	  <author>
		 <name>wayne_deng</name>
		 <uri>http://blog.waynedeng.com/</uri>
		 <email>wayne.deng.cn@gmail.com</email>
	  </author>
	  <category term="" scheme="http://blog.waynedeng.com/default.asp?cateID=47" label="ROR" /> 
	  <updated>2007-08-04T12:23:35+08:00</updated>
	  <published>2007-08-04T12:23:35+08:00</published>
		  <summary type="html"><![CDATA[Rails中防止SQL注入是非常简单的，但是还是要注意代码的编写习惯。<br/>例如：<br/>o&#114;der.find(:all, :conditions=&gt;&#34;name=&#39;#{name}&#39;&#34;)<br/>在conditions里面使用#()是非常不好的做法，这样传入数据库的sql语句不会经过任何的安全过滤。<br/><br/>正确的方法应该是使用占位符：<br/>o&#114;der.find(:all, :conditions=&gt;[&#34;name = ? and pay_type = ?&#34;, name, type])<br/>占位符使用起来比#()方便很多，你还可以这样：<br/>o&#114;der.find(:all, :conditions=&gt;[&#34;name = :name and pay_type = :pay_type&#34;, {:name=&gt;name, :pay_type=&gt;pay_type}])<br/><br/>甚至可以：<br/>o&#114;der.find(:all, :conditions=&gt;[&#34;name = :name and pay_type = :pay_type&#34;, params])<br/>因为params本身就是一个HASH，只要里面有name和pay_type的参数就会直接传递进来。<br/><br/>]]></summary>
	  <link rel="alternate" type="text/html" href="http://blog.waynedeng.com/default.asp?id=627" /> 
	  <id>http://blog.waynedeng.com/default.asp?id=627</id> 
  </entry>	
		
  <entry>
	  <title type="html"><![CDATA[Rails部署Mongrel+Apache]]></title>
	  <author>
		 <name>wayne_deng</name>
		 <uri>http://blog.waynedeng.com/</uri>
		 <email>wayne.deng.cn@gmail.com</email>
	  </author>
	  <category term="" scheme="http://blog.waynedeng.com/default.asp?cateID=47" label="ROR" /> 
	  <updated>2007-06-26T09:31:37+08:00</updated>
	  <published>2007-06-26T09:31:37+08:00</published>
		  <summary type="html"><![CDATA[在windows平台下面部署rails，一个比较好的选择就是Mongrel+Apache。<br/>Mongrel对rails的支持非常好，基本不需要什么配置，效率也不错，但是也有些弊病。例如一个Mongrel实例只能同时处理一个请求，不支持http compress（至少我没找到）。<br/>Apache就不用说了，工业标准，功能强大，就是配置稍显繁琐，对rails的支持限于fastCGI，据说Apache2还很不兼容。<br/>所以现在流行的一个搭配，就是集二者之所长，还可以使用Apache的http代理功能，启动多个mongrel进程实现可伸缩的负载均衡。<br/><br/>Mongrel的安装很简单：<br/>gem install mongrel –y<br/>gem install mongrel_service -y<br/>然后<br/>mongrel_rails service::install -N web1 -c c:\website -p 3000 –e production<br/>-N指明服务名称，-d指明rails应用的目录，-p是mongrel监听的tcp端口，-e是启动模式为生产模式<br/>即可创建rails网站系统服务。<br/>我们可以创建两个进程：<br/>mongrel_rails service::install -N web1 -c c:\website -p 3000 –e production<br/>mongrel_rails service::install -N web2 -c c:\website -p 3001 –e production<br/><br/><br/>Apache安装就不用介绍了，安装完毕以后修改httpd.conf文件，启用以下模块：<br/>LoadModule proxy_module modules/mod_proxy.so<br/>LoadModule proxy_balancer_module modules/mod_proxy_balancer.so<br/>LoadModule proxy_http_module modules/mod_proxy_http.so<br/>如果你希望对页面输出使用压缩，还需要这个模块：<br/>LoadModule deflate_module modules/mod_deflate.so<br/><br/>最后加上：<br/><div class="UBBPanel"><div class="UBBTitle"><img src="http://blog.waynedeng.com/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>#启用http压缩<br/>&lt;IfModule mod_deflate.c&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;AddOutputFilterByType DEFLATE text/html text/css text/javascript application/x-javascript<br/>&lt;/IfModule&gt;<br/><br/>#创建虚拟目录，让apache来处理javascript和css以及图片文件，分担mongrel的压力<br/>Alias /javascripts C:/website/public/javascripts<br/>Alias /stylesheets C:/website/public/stylesheets<br/>Alias /images C:/website/public/images<br/>#设置目录访问权限<br/>&lt;Directory C:/website/public/images&gt;<br/>&nbsp;&nbsp;o&#114;der allow,deny<br/>&nbsp;&nbsp;Allow from all<br/>&lt;/Directory&gt;&nbsp;&nbsp;<br/>&nbsp;&nbsp;<br/>&lt;Directory C:/website/public/javascripts&gt;<br/>&nbsp;&nbsp;o&#114;der allow,deny<br/>&nbsp;&nbsp;Allow from all<br/>&lt;/Directory&gt;&nbsp;&nbsp;<br/><br/>&lt;Directory C:/website/public/stylesheets&gt;<br/>&nbsp;&nbsp;o&#114;der allow,deny<br/>&nbsp;&nbsp;Allow from all<br/>&lt;/Directory&gt;&nbsp;&nbsp;<br/><br/>#设置负载代理，即mongrel进程<br/>ProxyRequests Off <br/>&lt;Proxy balancer://myCluster&gt; <br/>BalancerMember <a href="http://localhost:3000" target="_blank">http://localhost:3000</a><br/>BalancerMember <a href="http://localhost:3001" target="_blank">http://localhost:3001</a><br/>&lt;/Proxy&gt; <br/><br/>#apache监听80端口，将www.yourwebdomain.com的请求转发给mongrel负载代理，脚本，css，图片除外<br/>&lt;VirtualHost *:80&gt; <br/>ServerName www.yourwebdomain.com<br/>DocumentRoot C:/website/public<br/>ProxyPass /images ! <br/>ProxyPass /stylesheets ! <br/>ProxyPass /javascripts ! <br/>ProxyPass / balancer://myCluster/ <br/>ProxyPassReverse / balancer://myCluster/ <br/>ProxyPreserveHost on <br/>&lt;/VirtualHost&gt; <br/><br/></div></div><br/><br/>配置完毕，启动mongrel服务，apache服务就ok了。<br/>]]></summary>
	  <link rel="alternate" type="text/html" href="http://blog.waynedeng.com/default.asp?id=626" /> 
	  <id>http://blog.waynedeng.com/default.asp?id=626</id> 
  </entry>	
		
  <entry>
	  <title type="html"><![CDATA[在Model中使用session数据]]></title>
	  <author>
		 <name>wayne_deng</name>
		 <uri>http://blog.waynedeng.com/</uri>
		 <email>wayne.deng.cn@gmail.com</email>
	  </author>
	  <category term="" scheme="http://blog.waynedeng.com/default.asp?cateID=47" label="ROR" /> 
	  <updated>2007-06-23T16:33:56+08:00</updated>
	  <published>2007-06-23T16:33:56+08:00</published>
		  <summary type="html"><![CDATA[<p>Rails中MVC分割的非常清楚，在model中直接使用session是违反隔离规则的，rails会直接报错无法找到session变量。<br />虽然我们可以在controller中把session变量传递给model，但是在某些需求中我们还是可能会需要在model中使用session，例如在observer中记录操作人员的信息。</p>
<p>这篇文章就介绍了解决这个问题的方法：<br /><a href="http://www.zorched.net/2007/05/29/making-session-data-available-to-models-in-ruby-on-rails/">http://www.zorched.net/2007/05/29/making-session-data-available-to-models-in-ruby-on-rails/</a></p>
<p>Ruby on Rails is implemented as the Model View Controller (MVC) pattern. This pattern separates the context of the Web Application (in the Controller and the View) from the core Model of the application. The Model contains the Domain objects which encapsulate business logic, data retrieval, etc. The View displays information to the user and allows them to provide input to the application. The Controller handles the interactions between the View and the Model.</p>
<p>This separation is a very good design principle that generally helps prevent <a href="http://en.wikipedia.org/wiki/Spaghetti_code">spaghetti code</a>. Sometimes though the separation might break down.</p>
<p><strong><em><br />The following is really an alternative to using the <a href="http://api.rubyonrails.com/classes/ActionController/Caching/Sweeping.html">ActionController::Caching::Sweeper</a> which is a hybrid Model/Controller scoped Observer really. It seems to me, based on the name, that the intent is much more specific than giving Observers access to session data. Which do you prefer?<br /></em></strong></p>
<p>Rails provides the concept of a Model Observer. This Observer allows you to write code that will respond to the lifecycle events of the Model objects. For example you could log information every time a specific kind of Model object is saved. For example you could record some information every time an Account changed using the following Observer:<br /><code><br />class AccountObserver &lt; ActiveRecord::Observer<br />def after_update(record)<br />Audit.audit_change(record.account_id, record.new_balance)<br />end<br />end<br /></code></p>
<p>You might have noticed a limitation with the previous API though. You didn&rsquo;t notice? The only information passed to the Observer is the Object that is being changed. What if you want more context than this? For example, what if you want to audit not only the values that changed them, but the user who made the change?<br /><code><br />class AccountObserver &lt; ActiveRecord::Observer<br />def after_update(record)<br />Audit.audit_change(current_user, record.account_id, record.new_balance)<br />end<br />end<br /></code></p>
<p>How do you get the current_user value? Well, you have to plan ahead a little bit. The User in this application is stored in the HTTP Session when the user is authenticated. The session isn&rsquo;t directly available to the Model level (including the Observers) so you have to figure out a way around this. One way to accomplish this is by using a named <a href="http://www.ruby-doc.org/core/classes/Thread.html#M000484">Thread local variable</a>. Using <a href="http://mongrel.rubyforge.org/">Mongrel</a> as a web server, each HTTP request is served by its own thread. That means that a variable stored as thread local will be available for the entire processing of a request.</p>
<p>The UserInfo module encapsulates reading and writing the User object from/to the Thread local. This module can then be mixed in with other objects for easy access.<br /><code><br />module UserInfo<br />def current_user<br />Thread.current[:user]<br />end<br />&nbsp;<br />def self.current_user=(user)<br />Thread.current[:user] = user<br />end<br />end<br /></code></p>
<p>A <em>before_filter</em> set in the ApplicationController will be called before any action is called in any controller. You can take advantage of this to copy a value out of the HTTP session and set it in the Thread local:</p>
<p><code><br />class ApplicationController &lt; ActionController::Base<br />include UserInfo<br /># Pick a unique cookie name to distinguish our session data from others'<br />session :session_key =&gt; '_app_session_id'
<p>before_filter :set_user</p>
<p>protected<br />def authenticate<br />unless session[:user]<br />redirect_to :controller =&gt; &quot;login&quot;<br />return false<br />end<br />end</p>
<p># Sets the current user into a named Thread location so that it can be accessed<br /># by models and observers<br />def set_user<br />UserInfo.current_user = session[:user]<br />end<br />end<br /></p>
</code></p>
<p>At any point in an Observer of a Model class that you need to have access to those values you can just mixin the helper module and then use its methods to access the data. In this final example we mixin the UserInfo module to our AccountObserver and it will now have access to the current_user method:<br /><code><br />class AccountObserver &lt; ActiveRecord::Observer<br />include UserInfo<br />&nbsp;<br />def after_update(record)<br />Audit.audit_change(current_user, record.account_id, record.new_balance)<br />end<br />end<br /></code></p>
<p>You generally shouldn&rsquo;t need this kind of trick outside of an Observer. In most cases the Controller should pass all of the information needed by a Model object to it through its methods. That will allow the Model objects to interact and the Controller to do the orchestration needed. But in a few special cases, this trick might be handy.</p>]]></summary>
	  <link rel="alternate" type="text/html" href="http://blog.waynedeng.com/default.asp?id=625" /> 
	  <id>http://blog.waynedeng.com/default.asp?id=625</id> 
  </entry>	
		
  <entry>
	  <title type="html"><![CDATA[使FastCGI在IIS上运行Ruby on Rails网站]]></title>
	  <author>
		 <name>wayne_deng</name>
		 <uri>http://blog.waynedeng.com/</uri>
		 <email>wayne.deng.cn@gmail.com</email>
	  </author>
	  <category term="" scheme="http://blog.waynedeng.com/default.asp?cateID=47" label="ROR" /> 
	  <updated>2007-06-06T15:57:26+08:00</updated>
	  <published>2007-06-06T15:57:26+08:00</published>
		  <summary type="html"><![CDATA[<h1 class="entryviewheading"><font size="3">现在ROR也能在IIS上跑了，看看这篇文章：<br /><a href="http://mvolo.com/blogs/serverside/archive/2007/02/18/10-steps-to-get-Ruby-on-Rails-running-on-Windows-with-IIS-FastCGI.aspx">http://mvolo.com/blogs/serverside/archive/2007/02/18/10-steps-to-get-Ruby-on-Rails-running-on-Windows-with-IIS-FastCGI.aspx</a></font></h1>
<h1 class="entryviewheading"><font size="3">10 steps to get Ruby on Rails running on Windows with IIS FastCGI</font></h1>
<p>Since the original tech preview release of FastCGI last year, we've been seeing a lot of requests for getting Ruby on Rails running with our FastCGI.&nbsp; Theoretically, since the FastCGI component uses a standard protocol to support FastCGI-enabled applications, this shouldnt be an issue - but, in practice, this is very far from reality.&nbsp; After factoring in setup problems, configuration, and variations in runtime behavior / protocol deviations, every single FastCGI application we've looked at has required quite some effort to support properly.&nbsp; <br /><br />So, for FastCGI Tech Preview 2, I spent some time researching what it would take to enable Ruby on Rails, resulting in &quot;experimental&quot; RoR support in the TP2 release.&nbsp; It is &quot;experimental&quot; because we did only limited testing, and given our lack of experience with Ruby its very hard to tell whether a real Ruby application will work as expected at this point.<br /><br />I am confident that the experience can be improved significantly with community testing, and any necessary fixes to both the FastCGI component and Ruby.&nbsp; I am looking forward to any feedback/bug reports that can help us get there - please feel free to leave comments on the blog, or post to <a href="http://forums.iis.net/1103/ShowForum.aspx" target="links">IIS FastCGI forums</a>.&nbsp; </p>
<p>Without further ado, these are the 10 steps get RoR working with FastCGI TP2:<br /></p>
<h2>Read this first - platform limitations</h2>
<p>The steps below can be used to install Ruby on Rails on a <strong>Windows Server 2003 operating system</strong>, and configure it to work with the <strong><a href="http://www.iis.net/default.aspx?tabid=1000051" target="links">Microsoft IIS FastCGI technical preview 2 release</a></strong>.&nbsp; Unfortunately Windows XP does not support the required configuration necessary for the FastCGI TP2 component to run RoR, and Windows Vista's version of FastCGI TP2 uses a different mechanism to run RoR (post on how to get that working in the near future).&nbsp; The initial steps to install Ruby on Rails described here are similar for Windows XP, Windows Server 2003, and Windows Vista. </p>
<h2>FastCGI TP2 Installation</h2>
<p><span style="FONT-SIZE: large"><strong>1) </strong><a href="http://www.iis.net/default.aspx?tabid=1000051" target="links"><strong>Download and install FastCGI Technical Preview 2</strong></a></span></p>
<p>Download the appropriate TP2 package for your OS, which in this case means either the IIS6 32bit FastCGI or IIS6 64bit FastCGI.&nbsp; You can read <a href="http://mvolo.com/blogs/serverside/archive/2007/01/31/Turbo_2D00_charge-your-PHP-applications-with-IIS-FastCGI-Technical-Preview-2.aspx" target="links">more about this on my previous blog post</a>.&nbsp; Here is the synopsis of the install steps:</p>
<ul>
    <li><a title="links" href="http://www.iis.net/default.aspx?tabid=1000051" target="links">Download the appropriate FastCGI TP2 package</a> </li>
    <li>Unzip it to a local directory on your machine </li>
    <li>Use fcgisetup.js to install it:<br /><br />&gt; <strong>cscript fcgisetup.js /install</strong></li>
</ul>
<p>This will install FastCGI on your machine, and enable us to configure it manually later.&nbsp; We will not be using the automatic configuration support in the installer because we will need some customizations specific for RoR later.</p>
<h2>Ruby Installation</h2>
<p><strong><span style="FONT-SIZE: large">2) </span></strong><a href="http://rubyforge.org/frs/?group_id=167&amp;release_id=6672" target="links"><strong><span style="FONT-SIZE: large">Download and install Ruby</span></strong></a><strong><span style="FONT-SIZE: large"> </span></strong>(latest tested version was&nbsp;<strong> </strong><strong><span style="COLOR: #cc3333">1.8.5-22 Final</span></strong>)<br /><br /><strong><span style="FONT-SIZE: large">3) Install Rails<br /></span></strong><br />Open a new command line window, and run the gem installer: <br /><br />&gt; <strong><span style="FONT-SIZE: medium">gem install rails --include-dependencies</span></strong><br /><br /><img height="326" src="http://mvolo.com/files/ruby/gem_install_rails.jpg" width="667" alt="" />&nbsp;<br /><br /><span style="FONT-SIZE: large"><strong>4) </strong><a href="http://rubyforiis.sosukodo.org/" target="links"><strong>Download and install RoR IIS extensions</strong></a></span><br /><br />The RubyForIIS.exe package contains the FastCGI client library on which RoR is dependent in order to use its dispatch.fcgi script.&nbsp; During the installation, the installer will ask for the location of the Ruby directory - <strong>be sure to point the installer to the directory where you installed Ruby</strong>, for example, f:\Ruby.<br /><br /><img height="286" src="http://mvolo.com/files/ruby/RubyForIIS_install.jpg" width="425" alt="" /><br /><br />During the installation, you may get an error &quot;Unable to write to file ...\msvcp7.dll&quot;&nbsp; - press ignore to continue.&nbsp; If you want to double-check that everything went well, open a command prompt, and type in:<br />&gt; <strong>irb</strong> &lt;enter&gt;<br />&gt; <strong>require 'fcgi' </strong>&lt;enter&gt;<br />If you see &quot;true&quot;, then its installed correctly.&nbsp; If not, re-install and give the right path this time. </p>
<p><span style="FONT-SIZE: large"><strong>5) Fix the Ruby CGI script</strong></span></p>
<p>This is a workaround for an IIS-specific behavior in Ruby that actually does not work with IIS.&nbsp; Feel the irony.&nbsp; Quick background - NPH, or No Parsed Headers, is a CGI mode of operation in which the CGI program produces a complete response including the http headers, instead of supplying the headers to the web server and letting the webserver manage them.&nbsp; Most of today's webservers, including IIS, manage response headers on their own - for example, IIS enables a number of web server features that modify response headers in order to enable functionality like caching, compression, etc.&nbsp; Ruby's CGI script assumes that IIS always requires NPH, and this of course completely breaks the FastCGI component because it does not even support NPH :)&nbsp; The funnier thing is that even IIS CGI does not require NPH, and doesnt use it by default.&nbsp; This is one of the things that totally makes sense to be fixed in a future Rails release to provide a more cohesive experience on IIS.<br /><br />Open <strong><span style="FONT-SIZE: medium">&lt;f:\Ruby&gt;\lib\ruby\1.8\cgi.rb</span></strong>, and edit <span style="FONT-SIZE: medium"><strong>line 559</strong></span> of the script to remove: <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot;<strong><span style="FONT-SIZE: medium">OR /IIS/n.match(env_table([&lsquo;SERVER_SOFTWARE&rsquo;])</span></strong>&quot;.</p>
<p>You can also <a href="http://mvolo.com/files/ruby/cgi.rb.txt">download the already fixed script</a>&nbsp; if you dont want to do surgery yourself.</p>
<h2>Creating a sample Ruby application</h2>
<p>At this point, if you followed the instructions above, you should have Ruby on Rails installed and ready to go on your Windows machine.&nbsp; Now, we will create a sample RoR application to use with the FastCGI component:</p>
<p><strong><span style="FONT-SIZE: large">6) Create a sample Ruby app</span></strong></p>
<p>Open a command line window, change to a base directory where you want to create your app, and type:</p>
<p>&gt; <strong>rails myapp<br /></strong>&gt; <strong>cd myapp<br /></strong>&gt; <strong>ruby script\generate controller test</strong></p>
<p>This creates the <strong>myapp </strong>RoR application, and then generates a sample &quot;test&quot; RoR controller.&nbsp; Edit this controller to display some useful stuff by opening <strong>app\controller\test_controller.rb</strong>, and pasting the following into it:</p>
<p><strong>class TestController &lt; ApplicationController <br />&nbsp; def index <br />&nbsp; &nbsp; render :text=&gt;&quot;The index action&quot; <br />&nbsp; end <br />&nbsp; def about <br />&nbsp; &nbsp; render :text=&gt;&quot;Testing app v1.0&quot; <br />&nbsp; end <br />end</strong></p>
<h2>Configure the RoR application with IIS and FastCGI</h2>
<p>We are almost there, so don't panic.&nbsp; I promise to not exceed 10 steps :)</p>
<p><span style="FONT-SIZE: large">7) Create a website for your RoR app</span></p>
<p>Create a new website on port 81 pointing to the <strong>public</strong> directory of your rails app, which for me was <strong>f:\ruby\myapp\public:</strong></p>
<p><img height="501" src="http://mvolo.com/files/ruby/create_ruby_website.jpg" width="766" alt="" />&nbsp;</p>
<p><span style="FONT-SIZE: large">8) Create the RoR FastCGI handler mapping</span></p>
<p>Because RoR uses SEF (search engine friendly) urls, it needs to use a wildcard mapping to forward all requests to FastCGI / RoR mapping - unlike PHP, which requires .PHP files to be mapped to the PHP / FastCGI mapping.&nbsp; Because of reliance on wildcard mapping, FastCGI can only be used to run RoR on Windows Server 2003 (since Windows XP's version of IIS doesnt support wildcard mappings).&nbsp; This is the sole reason why this walkthrough is limited to W2k3.<br /><br />To create the mapping, click the &quot;Configuration&quot; button on the website, and &quot;Insert&quot; the handler mapping to &quot;fcgiext.dll&quot; FastCGI ISAPI handler (which you installed in step 1):<br /><br /><img id="IMG1" height="500" src="http://mvolo.com/files/ruby/create_wildcard_mapping.jpg" width="767" alt="" /></p>
<p>Be sure to clear the &quot;Verify that file exists&quot; checkbox.</p>
<p><span style="FONT-SIZE: large">9) Create the FastCGI application pool for your website</span></p>
<p>If you remember in step 1, when we installed the FastCGI TP2 package, we didnt use the installer's support for registering a FastCGI program.&nbsp; This is because RoR requires some custom settings in the FastCGI config file that the installer doesnt surface.&nbsp; <br /><br />Because of this, we will manually create this configuration by editing the <strong>%windir%\system32\inetsrv\fcgiext.ini</strong> configuration file (NOTE that for 64bit installations, you will also need to make the same edits to <strong>%windir%\syswow64\inetsrv\fcgiext.ini</strong>):</p>
<p><strong><span style="FONT-SIZE: medium">[Types] </span><br />*:<span style="COLOR: #ff0000">85358523</span>=Ruby <br /><br /><span style="FONT-SIZE: medium">[Ruby] </span><br />ExePath=<span style="COLOR: #ff0033">F:\Ruby\bin\ruby.exe</span> <br />Arguments=<span style="COLOR: #ff0000">F:\Ruby\myapp\public\dispatch.fcgi</span> <br />IgnoreDirectories=0 <br />IgnoreExistingFiles=1<br />QueueLength=1000 <br />MaxInstances=4 <br />InstanceTimeout=30 <br />InstanceMaxRequests=200 </strong><br /></p>
<p>- Replace the <strong>ExePath</strong> with the path to your ruby.exe.<br />- Replace the <strong>Arguments</strong> with the path the dispatch.fcgi script inside your application.<br />- Replace the &quot;<strong>85358523</strong>&quot; number above with your site id.&nbsp; You could omit this if you are not planning to run multiple Ruby applications on your machine. You can get it from the logging properties of your website:&nbsp;</p>
<p><img height="481" src="http://mvolo.com/files/ruby/get_site_id.jpg" width="779" alt="" />&nbsp;</p>
<p>This configuration shows the several new configuration / behavior features we needed to add to TP2 in order to get Ruby working.&nbsp; This includes support for specifying arguments to the FastCGI executable (per pool), the ability to scope FastCGI extension mappings to a particular site id (so that you can map the same extension to different pools for different sites), and the ability to execute as a wildcard mapping that only processes files that do not exist on disk.&nbsp; More information on all of these later.<br /><br /><span style="FONT-SIZE: large">10) You are done!</span></p>
<p>At this point, you should be up and running.&nbsp; Hit up <strong>http://localhost:81/test/about</strong>, and you should get the RoR response from our test controller.</p>
<p><span>Please try this out with your real RoR apps, and let me know how it went / what issues you hit.&nbsp; Your feedback will be instrumental in getting to a production quality FastCGI support for RoR in a future release.&nbsp; Feel free to leave comments on this blog, or hit us up at the <a href="http://forums.iis.net/1103/ShowForum.aspx" target="links">FastCGI forums</a> on <a href="http://www.iis.net/">www.iis.net</a>.<br /><br />Finally, I want to thank <a title="bh" href="http://wiki.rubyonrails.org/rails/pages/Brian+Hogan" target="_blank">Brian Hogan</a>, without whose invaluable help in explaining the workings of Ruby On Rails and how to get it installed on Windows, I wouldn't have been able to get even this far.&nbsp; He has a book on Ruby on Rails coming out soon, and I hope that we can get IIS FastCGI and RoR to play well enough together to be mentioned in it :)</span></p>
<div class="entryviewfooter">Published 18 February 07 12:53 by <a id="ctl00___ctl00___ctl01___Entry___AuthorLink" href="http://mvolo.com/user/Profile.aspx?UserID=2102">Mike Volodarsky</a> </div>]]></summary>
	  <link rel="alternate" type="text/html" href="http://blog.waynedeng.com/default.asp?id=623" /> 
	  <id>http://blog.waynedeng.com/default.asp?id=623</id> 
  </entry>	
		
  <entry>
	  <title type="html"><![CDATA[HAProxy]]></title>
	  <author>
		 <name>wayne_deng</name>
		 <uri>http://blog.waynedeng.com/</uri>
		 <email>wayne.deng.cn@gmail.com</email>
	  </author>
	  <category term="" scheme="http://blog.waynedeng.com/default.asp?cateID=47" label="ROR" /> 
	  <updated>2007-06-06T14:21:42+08:00</updated>
	  <published>2007-06-06T14:21:42+08:00</published>
		  <summary type="html"><![CDATA[<p>这是一个高性能、高伸缩性的<a href="http://www.rubyonrails.org/">Rails</a>部署方案。有一组<a href="http://blog.kovyrin.net/2006/08/22/high-performance-rails-nginx-lighttpd-mongrel/">性能数据</a>可供参考。</p>
<p>首先接收到HTTP请求的是<a href="http://haproxy.1wt.eu/">HAProxy</a>。HAProxy会把请求反向代理给其后的多个<a href="http://mongrel.rubyforge.org/">Mongrel</a>实例。每个Mongrel实例同一时间只处理一个请求。只要Rails应用本身贯彻<a href="http://zefhemel.com/archives/2004/09/01/the-share-nothing-architecture">无共享架构</a>，就可以直接通过增加服务器和改变HAProxy配置得到线性的性能提升。另外可以用<a href="http://www.tildeslash.com/monit/">Monit</a>来管理Mongrel实例的开启和关闭，并且在异常状况发生时及时采取措施。这样一来，企业级超复杂所暗含的性能、伸缩性、可管理性等等要求都满足了。</p>
<p>&ldquo;HAProxy is a free, <strong><em>very</em></strong> fast and reliable solution offering <a href="http://en.wikipedia.org/wiki/High_availability">high availability</a>, <a href="http://en.wikipedia.org/wiki/Load_balancer">load balancing</a>, and proxying for TCP and HTTP-based applications.&rdquo;<br />&ldquo;Mongrel is a fast HTTP library and server for Ruby that is intended for hosting Ruby web applications of any kind using plain HTTP rather than FastCGI or SCGI.&rdquo;<br />&ldquo;monit is a utility for managing and monitoring, processes, files, directories and devices on a UNIX system.&rdquo;</p>
<p>转自：<a href="http://gigix.thoughtworkers.org/articles/2007/04/24/deploy-rails-app-with-haproxy-and-mongrel">http://gigix.thoughtworkers.org/articles/2007/04/24/deploy-rails-app-with-haproxy-and-mongrel</a></p>]]></summary>
	  <link rel="alternate" type="text/html" href="http://blog.waynedeng.com/default.asp?id=622" /> 
	  <id>http://blog.waynedeng.com/default.asp?id=622</id> 
  </entry>	
		
  <entry>
	  <title type="html"><![CDATA[Rails Migration参考（一）]]></title>
	  <author>
		 <name>wayne_deng</name>
		 <uri>http://blog.waynedeng.com/</uri>
		 <email>wayne.deng.cn@gmail.com</email>
	  </author>
	  <category term="" scheme="http://blog.waynedeng.com/default.asp?cateID=47" label="ROR" /> 
	  <updated>2007-05-28T17:45:02+08:00</updated>
	  <published>2007-05-28T17:45:02+08:00</published>
		  <summary type="html"><![CDATA[更新到最新版本：<br/>rake db:migrate<br/>重设数据库：<br/>rake db:migrate VERSION=0<br/><br/><br/><strong>字段操作</strong><br/><br/>1、字段类型<br/>:binary, :boolean, :date, :datetime, :float, :integer, :string, :text, :time, :timestamp<br/><br/>2、add_column 添加字段<br/>参数<br/>:null =&gt; true o&#114; false 是否可为null<br/>:limit =&gt; size&nbsp;&nbsp;字段大小，通常是string字段的长度<br/>:default =&gt; value 缺省的值<br/><br/>add_column :orders, :placed_at, :datetime, :default =&gt; Time.now<br/><br/>3、rename_column 字段名修改<br/>class RenameEmailColumn &lt; ActiveRecord::Migration<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def self.up<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rename_column :orders, :e_mail, :customer_email<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end<br/>&nbsp;&nbsp;&nbsp;&nbsp; def self.down<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rename_column :orders, :customer_email, :e_mail<br/>&nbsp;&nbsp;&nbsp;&nbsp; end<br/>end<br/><br/>4、change_column&nbsp;&nbsp;字段类型属性修改<br/>def self.up<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; change_column :orders, :order_type, :string, :null =&gt; false<br/>end<br/>def self.down<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; change_column :orders, :order_type, :integer<br/>end<br/><br/><strong>表操作</strong><br/>class Cr&#101;ateOrderHistories &lt; ActiveRecord::Migration<br/>&nbsp;&nbsp;&nbsp;&nbsp;def self.up<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cr&#101;ate_table :order_histories do |t|<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t.column :order_id, :integer, :null =&gt; false<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t.column :cr&#101;ated_at, :timestamp<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t.column :notes, :text<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end<br/>&nbsp;&nbsp;&nbsp;&nbsp;end<br/>&nbsp;&nbsp;&nbsp;&nbsp;def self.down<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dro&#112;_table :order_histories<br/>&nbsp;&nbsp;&nbsp;&nbsp;end<br/>end<br/><br/>重命名rename_table<br/><br/><strong>索引</strong><br/>class AddCustomerNameIndexToOrders &lt; ActiveRecord::Migration<br/>&nbsp;&nbsp;&nbsp;&nbsp;def self.up<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; add_index :orders, :name<br/>&nbsp;&nbsp;&nbsp;&nbsp;end<br/>&nbsp;&nbsp;&nbsp;&nbsp;def self.down<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; remove_index :orders, :name<br/>&nbsp;&nbsp;&nbsp;&nbsp;end<br/>end<br/><br/>PK<br/>cr&#101;ate_table :tickets, <span style="color:Red">:primary_key </span>=&gt; :ticket_number do |t|<br/>&nbsp;&nbsp;&nbsp;&nbsp;t.column :cr&#101;ated_at, :timestamp<br/>&nbsp;&nbsp;&nbsp;&nbsp;t.column :description, :text<br/>end<br/><br/><br/><br/>raise ActiveRecord::IrreversibleMigration 不可逆错误<br/><br/>class ChangeOrderTypeToString &lt; ActiveRecord::Migration<br/>&nbsp;&nbsp;&nbsp;&nbsp;def self.up<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;change_column :orders, :order_type, :string, :null =&gt; false<br/>&nbsp;&nbsp;&nbsp;&nbsp;end<br/>&nbsp;&nbsp;&nbsp;&nbsp;def self.down<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;raise ActiveRecord::IrreversibleMigration<br/>&nbsp;&nbsp;&nbsp;&nbsp;end<br/>end]]></summary>
	  <link rel="alternate" type="text/html" href="http://blog.waynedeng.com/default.asp?id=621" /> 
	  <id>http://blog.waynedeng.com/default.asp?id=621</id> 
  </entry>	
		
  <entry>
	  <title type="html"><![CDATA[Ruby笔记（一）]]></title>
	  <author>
		 <name>wayne_deng</name>
		 <uri>http://blog.waynedeng.com/</uri>
		 <email>wayne.deng.cn@gmail.com</email>
	  </author>
	  <category term="" scheme="http://blog.waynedeng.com/default.asp?cateID=47" label="ROR" /> 
	  <updated>2007-05-26T14:45:10+08:00</updated>
	  <published>2007-05-26T14:45:10+08:00</published>
		  <summary type="html"><![CDATA[1、||=<br/>session[:cart] ||= Cart.new，这个用法让很多人看不明白。其实这样就好理解了：<br/>session[:cart] = session[:cart] || Cart.new<br/><br/>有点类似于i+=1的用法，||就是OR。可能你会问逻辑表达式返回的值不是true或者false吗？为什么会是session[:cart]或者Cart.new呢？这就和Ruby的特性有关了，Ruby中只有nil是false，其它所有都是true，逻辑表达式返回的就是变量的值，只要非nil就是true，一点都不矛盾。<br/><br/>2、item = @items.find{|i| i.product_id == product.id}<br/>又是一个极其简单的语句，而且非常人性化的表达方式。<br/>在@items里面查找product_id为product.id的项。item = @item.查找{|i| i.product_id == product.id}<br/><br/>传统的方法就是：<br/><div class="UBBPanel"><div class="UBBTitle"><img src="http://blog.waynedeng.com/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>item = nil<br/>for i in @item<br/>&nbsp;&nbsp;if i.product_id == product.id<br/>&nbsp;&nbsp;&nbsp;&nbsp; item = i<br/>&nbsp;&nbsp;end<br/>end<br/></div></div><br/><br/>6句精简成一句，而且更贴切人类的语言！<br/>不过find不是对所有的集合对象都可以使用，但是你一旦定义了&lt;=&gt;操作符便会自动获得find，each等Enumerable具有的方法。]]></summary>
	  <link rel="alternate" type="text/html" href="http://blog.waynedeng.com/default.asp?id=620" /> 
	  <id>http://blog.waynedeng.com/default.asp?id=620</id> 
  </entry>	
		
  <entry>
	  <title type="html"><![CDATA[用Ruby开发windows程序的工具]]></title>
	  <author>
		 <name>wayne_deng</name>
		 <uri>http://blog.waynedeng.com/</uri>
		 <email>wayne.deng.cn@gmail.com</email>
	  </author>
	  <category term="" scheme="http://blog.waynedeng.com/default.asp?cateID=47" label="ROR" /> 
	  <updated>2007-05-26T13:09:45+08:00</updated>
	  <published>2007-05-26T13:09:45+08:00</published>
		  <summary type="html"><![CDATA[GUI TOOLKIT: wxRuby<br/>图形界面开发工具<br/><a href="http://rubyforge.org/projects/wxruby/" target="_blank">http://rubyforge.org/projects/wxruby/</a><br/><a href="http://wxruby.rubyforge.org/wiki/wiki.pl?Installation" target="_blank">http://wxruby.rubyforge.org/wiki/wiki.pl?Installation</a><br/><a href="http://eastviking.javaeye.com/blog/34022" target="_blank">http://eastviking.javaeye.com/blog/34022</a> 这是一篇中文的介绍<br/><br/>COMPILER: RubyScript2Exe<br/>将Ruby程序编译成EXE文件。<br/><a href="http://www.erikveen.dds.nl/rubyscri&#112;t2exe/index.html" target="_blank">http://www.erikveen.dds.nl/rubyscri&#112;t2exe/index.html</a><br/><br/>INSTALLER: Inno Setup<br/><a href="http://www.jrsoftware.org/isinfo.php" target="_blank">http://www.jrsoftware.org/isinfo.php</a><br/>安装打包工具]]></summary>
	  <link rel="alternate" type="text/html" href="http://blog.waynedeng.com/default.asp?id=619" /> 
	  <id>http://blog.waynedeng.com/default.asp?id=619</id> 
  </entry>	
		
</feed>