<?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"
	>

<channel>
	<title>CrazyRails ~ Flex on Ruby on Rails</title>
	<atom:link href="http://crazyrails.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://crazyrails.com</link>
	<description>Open Source Technologies on Mac &#38; Linux</description>
	<pubDate>Fri, 04 Jul 2008 21:38:45 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.5.1</generator>
	<language>en</language>
			<item>
		<title>How to quickly import/export MySQL database scripts</title>
		<link>http://crazyrails.com/how-to-quickly-importexport-mysql-database-scripts/</link>
		<comments>http://crazyrails.com/how-to-quickly-importexport-mysql-database-scripts/#comments</comments>
		<pubDate>Tue, 13 May 2008 02:53:27 +0000</pubDate>
		<dc:creator>Marty</dc:creator>
		
		<category><![CDATA[Linux]]></category>

		<category><![CDATA[Mac OS X]]></category>

		<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://crazyrails.com/how-to-quickly-importexport-mysql-database-scripts/</guid>
		<description><![CDATA[# Export MySQL Database Script
 mysqldump -uroot -p db_name_1 &#62; dump_name.sql
# Import MySQL Database Script
 mysql -uroot -p db_name_2 &#60; dump_name.sql
Importing a MySQL database script (.sql) will potentially overwrite data!  (That&#8217;s what it&#8217;s supposed to do.)   Make sure you know that what you&#8217;re doing is safe!-)
Done!
]]></description>
			<content:encoded><![CDATA[<p># Export MySQL Database Script</p>
<blockquote><p> mysqldump -uroot -p db_name_1 &gt; dump_name.sql</p></blockquote>
<p># Import MySQL Database Script</p>
<blockquote><p> mysql -uroot -p db_name_2 &lt; dump_name.sql</p></blockquote>
<p>Importing a MySQL database script (.sql) will potentially overwrite data!  (That&#8217;s what it&#8217;s supposed to do.)   Make sure you know that what you&#8217;re doing is safe!-)</p>
<p><strong>Done!</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://crazyrails.com/how-to-quickly-importexport-mysql-database-scripts/feed/</wfw:commentRss>
		</item>
		<item>
		<title>What rubygems does Mac OS X Leopard come pre-installed with?</title>
		<link>http://crazyrails.com/what-rubygems-does-mac-os-x-leopard-come-pre-installed-with/</link>
		<comments>http://crazyrails.com/what-rubygems-does-mac-os-x-leopard-come-pre-installed-with/#comments</comments>
		<pubDate>Sun, 11 May 2008 02:52:45 +0000</pubDate>
		<dc:creator>Marty</dc:creator>
		
		<category><![CDATA[Ruby on Rails]]></category>

		<category><![CDATA[gems]]></category>

		<category><![CDATA[leopard]]></category>

		<category><![CDATA[mac os x]]></category>

		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://crazyrails.com/what-rubygems-does-mac-os-x-leopard-come-pre-installed-with/</guid>
		<description><![CDATA[

actionmailer (1.3.6, 1.3.3)
actionpack (1.13.6, 1.13.3)
actionwebservice (1.2.6, 1.2.3)
activerecord (1.15.6, 1.15.3)
activesupport (1.4.4, 1.4.2)
acts_as_ferret (0.4.1)
capistrano (2.0.0)
cgi_multipart_eof_fix (2.2)
daemons (1.0.7)
dnssd (0.6.0)
fastthread (1.0)
fcgi (0.8.7)
ferret (0.11.4)
gem_plugin (0.2.2)
highline (1.2.9)
hpricot (0.6)
libxml-ruby (0.3.8.4)
mongrel (1.0.1)
needle (1.3.0)
net-sftp (1.1.0)
net-ssh (1.1.2)
rails (1.2.6, 1.2.3)
rake (0.7.3)
RedCloth (3.0.4)
rspec (1.1.3)
ruby-openid (1.1.4)
ruby-yadis (0.3.4)
rubynode (0.1.3)
sources (0.0.1)
sqlite3-ruby (1.2.1)
termios (0.9.4)

]]></description>
			<content:encoded><![CDATA[<p><span id="more-25"></span>
<ul>
<li>actionmailer (1.3.6, 1.3.3)</li>
<li>actionpack (1.13.6, 1.13.3)</li>
<li>actionwebservice (1.2.6, 1.2.3)</li>
<li>activerecord (1.15.6, 1.15.3)</li>
<li>activesupport (1.4.4, 1.4.2)</li>
<li>acts_as_ferret (0.4.1)</li>
<li>capistrano (2.0.0)</li>
<li>cgi_multipart_eof_fix (2.2)</li>
<li>daemons (1.0.7)</li>
<li>dnssd (0.6.0)</li>
<li>fastthread (1.0)</li>
<li>fcgi (0.8.7)</li>
<li>ferret (0.11.4)</li>
<li>gem_plugin (0.2.2)</li>
<li>highline (1.2.9)</li>
<li>hpricot (0.6)</li>
<li>libxml-ruby (0.3.8.4)</li>
<li>mongrel (1.0.1)</li>
<li>needle (1.3.0)</li>
<li>net-sftp (1.1.0)</li>
<li>net-ssh (1.1.2)</li>
<li>rails (1.2.6, 1.2.3)</li>
<li>rake (0.7.3)</li>
<li>RedCloth (3.0.4)</li>
<li>rspec (1.1.3)</li>
<li>ruby-openid (1.1.4)</li>
<li>ruby-yadis (0.3.4)</li>
<li>rubynode (0.1.3)</li>
<li>sources (0.0.1)</li>
<li>sqlite3-ruby (1.2.1)</li>
<li>termios (0.9.4)</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://crazyrails.com/what-rubygems-does-mac-os-x-leopard-come-pre-installed-with/feed/</wfw:commentRss>
		</item>
		<item>
		<title>What does a mac/linux developer&#8217;s ~/.bashrc file look like?</title>
		<link>http://crazyrails.com/what-does-a-maclinux-developers-bashrc-file-look-like/</link>
		<comments>http://crazyrails.com/what-does-a-maclinux-developers-bashrc-file-look-like/#comments</comments>
		<pubDate>Fri, 02 May 2008 23:21:07 +0000</pubDate>
		<dc:creator>Marty</dc:creator>
		
		<category><![CDATA[Ruby on Rails]]></category>

		<category><![CDATA[bash]]></category>

		<guid isPermaLink="false">http://crazyrails.com/what-does-a-maclinux-developers-bashrc-file-look-like/</guid>
		<description><![CDATA[Well, here&#8217;s an example of mine.  Run &#8216;mate ~/.bashrc&#8217; to view and edit the file, then save it and run &#8217;source ~/.bash_profile&#8217; (on Mac) or whatever your shell equivalent is.  Then, you can just use the aliases &#8216;bashrc&#8217; and &#8217;sourceb&#8217; if you choose to set these aliases as I have.

# terminal colors
export PS1=&#8217;\033[32;1m\]mac:\[\033[1;32m\]\w
$\[\033[00m\] &#8216;
export TERM=xterm-color
# [...]]]></description>
			<content:encoded><![CDATA[<p>Well, here&#8217;s an example of mine.  Run &#8216;mate ~/.bashrc&#8217; to view and edit the file, then save it and run &#8217;source ~/.bash_profile&#8217; (on Mac) or whatever your shell equivalent is.  Then, you can just use the aliases &#8216;bashrc&#8217; and &#8217;sourceb&#8217; if you choose to set these aliases as I have.</p>
<p><span id="more-23"></span></p>
<p># terminal colors<br />
export PS1=&#8217;\033[32;1m\]mac:\[\033[1;32m\]\w<br />
$\[\033[00m\] &#8216;<br />
export TERM=xterm-color</p>
<p># aliases<br />
alias ls=&#8217;ls -G -a&#8217;<br />
alias svna=&#8217;svn add . &#8211;force&#8217;<br />
alias svnc=&#8217;svn commit -m&#8217;<br />
alias svnd=&#8217;svn delete&#8217;<br />
alias svne=&#8217;svn propset svn:executable&#8217;<br />
alias svni=&#8217;svn propset svn:ignore&#8217;<br />
alias svnr=&#8217;svn rename&#8217;<br />
alias svns=&#8217;svn status&#8217;<br />
alias bashrc=&#8217;mate ~/.bashrc&#8217;<br />
alias sourceb=&#8217;source ~/.bash_profile&#8217;</p>
<p># set environment paths<br />
export PATH=~/source/rails<br />
export PATH=$PATH:~/source/django</p>
<p>export PATH=$PATH:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/X11/bin<br />
export MANPATH=/usr/share/man:/usr/local/share/man:/usr/X11/man</p>
<p># add mysql location<br />
export PATH=$PATH:/usr/local/mysql/bin</p>
<p># add macports locations<br />
export PATH=$PATH:/opt/local/bin:/opt/local/sbin:/opt/local/var<br />
export MANPATH=$MANPATH:/opt/local/share/man</p>
<p># add jhbuild location<br />
export PATH=$PATH:~/bin</p>
<p># add pkgconfig location<br />
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig</p>
<p># add gtk location<br />
export PATH=/opt/gtk/bin:$PATH</p>
<p># add ladspa location<br />
export LADSPA_PATH=/usr/local/lib/ladspa</p>
<p># add Flex SDK location<br />
export FLEX_HOME=~/source/flex3sdk<br />
export PATH=$PATH:$FLEX_HOME/bin</p>
<p># add mxml generator location<br />
export PATH=$PATH:~/mxml_location</p>
<p># apache ant<br />
export ANT_HOME=/usr/bin/ant<br />
export JAVA_HOME=/usr/bin/java<br />
export PATH=${PATH}:${ANT_HOME}/bin</p>
]]></content:encoded>
			<wfw:commentRss>http://crazyrails.com/what-does-a-maclinux-developers-bashrc-file-look-like/feed/</wfw:commentRss>
		</item>
		<item>
		<title>How to move a Subversion repository to a different server location</title>
		<link>http://crazyrails.com/how-to-move-a-subversion-repository-to-a-different-server-location/</link>
		<comments>http://crazyrails.com/how-to-move-a-subversion-repository-to-a-different-server-location/#comments</comments>
		<pubDate>Mon, 21 Apr 2008 04:05:34 +0000</pubDate>
		<dc:creator>Marty</dc:creator>
		
		<category><![CDATA[Subversion]]></category>

		<guid isPermaLink="false">http://crazyrails.com/how-to-move-a-subversion-repository-to-a-different-server-location/</guid>
		<description><![CDATA[Okay, so let&#8217;s say you host a subversion repository on one server and need to completely move or copy it to a different server or server location.  The Tigris guys make it very easy.  This information is explained in more detail in the free Subversion PDF titled &#8220;Version Control with Subversion 1.4&#8243; starting on page [...]]]></description>
			<content:encoded><![CDATA[<p>Okay, so let&#8217;s say you host a subversion repository on one server and need to completely move or copy it to a different server or server location.  The Tigris guys make it very easy.  This information is explained in more detail in the free Subversion PDF titled <a href="http://svnbook.red-bean.com/" title="Free SVN Guide" target="_blank">&#8220;Version Control with Subversion 1.4&#8243;</a> starting on page 126.  I find it easier here.</p>
<p><span id="more-22"></span></p>
<p># Run these commands from <strong>current</strong> Subversion repository server&#8217;s svn root directory</p>
<blockquote><p><strong>cd ~/rep/svn</strong><br />
svnlook youngest myproject1<br />
# &gt; 1234<br />
# we want record of ALL revisions, so we need to specify from<br />
# revision 1 to revision X, in this case 1:1234<br />
<strong>svnadmin dump myproject1 -r 1:1234 &gt; myproject1_dumpfile_r1-1234</strong><br />
# * Dumped revision 1.<br />
# * Dumped revision 2.<br />
# * &#8230;<br />
# * Dumped revision 1234.</p></blockquote>
<p># Now you need to get this dumpfile over to your new server.<br />
# I like to use secure copy &#8220;scp&#8221; to quickly download the file<br />
# to my local machine, then immediately upload it to the new server.<br />
# You, of course, can do this any way you like.<br />
# Some people like to use a graphical FTP also (I like CyberDuck).</p>
<p># on local machine: <strong>cd ~/</strong></p>
<blockquote><p> # download with &#8220;scp [from] [to]&#8221;<br />
<strong>scp super@111.222.333.444:/home/super/rep/svn/myproject1_dumpfile_r</strong><strong>1-</strong><strong>1234 ~/work/projects/myproject1_dumpfile_r</strong><strong>1-</strong><strong>1234</strong><br />
# &gt; myproject1_dumpfile_r<strong>1-</strong>1234 =====&gt; 100%   10MB 336.1KB/s   00:31</p>
<p># upload with &#8220;scp [from] [to]&#8221;<br />
<strong>scp ~/work/projects/myproject1_dumpfile_r</strong><strong>1-</strong><strong>1234 super@111.222.333.444:/home/super/rep/svn/myproject1_dumpfile_r</strong><strong>1-</strong><strong>1234</strong><br />
# &gt; myproject1_dumpfile_r<strong>1-</strong>1234 =====&gt; 100%   10MB  81.4KB/s   02:08</p></blockquote>
<p># Now &#8220;load&#8221; the dump file onto your <strong>new</strong> Subversion server with these commands</p>
<blockquote><p><strong>cd ~/rep/svn<br />
</strong>svnlook youngest myproject2<br />
# &#8230;if new repo doesn&#8217;t exist already, you&#8217;ll see<br />
# &gt; No such file or directory<br />
# &#8230;or if repo does exist, then revision number is displayed<br />
# &gt; 1211<br />
<strong>svnadmin load myproject2 &lt; myproject1_dumpfile_r1-1234<br />
</strong># you should see a lot of output, and at the end:<br />
# &gt; &#8212;&#8212;- Committed revision 1234 &gt;&gt;&gt;<strong><br />
</strong></p></blockquote>
<p><strong>Done!<br />
</strong>That was crazy easy!</p>
]]></content:encoded>
			<wfw:commentRss>http://crazyrails.com/how-to-move-a-subversion-repository-to-a-different-server-location/feed/</wfw:commentRss>
		</item>
		<item>
		<title>How to install RESTful Authentication on a Ruby on Rails 2.0 application</title>
		<link>http://crazyrails.com/how-to-install-restful-authentication/</link>
		<comments>http://crazyrails.com/how-to-install-restful-authentication/#comments</comments>
		<pubDate>Wed, 09 Apr 2008 19:19:21 +0000</pubDate>
		<dc:creator>Marty</dc:creator>
		
		<category><![CDATA[Linux]]></category>

		<category><![CDATA[Mac OS X]]></category>

		<category><![CDATA[Ruby on Rails]]></category>

		<category><![CDATA[REST]]></category>

		<category><![CDATA[security]]></category>

		<guid isPermaLink="false">http://crazyrails.com/?p=1</guid>
		<description><![CDATA[It&#8217;s time to upgrade your Rails 2.0 application with user authentication, and we hear that RESTful Authentication is the way to go, but all the instructions out there (even on the plugin repository sites) are out of date or don&#8217;t completely work or only work on Rails 1.2.x.  In this tutorial, however, we&#8217;ll go step-by-step [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s time to upgrade your Rails 2.0 application with user authentication, and we hear that RESTful Authentication is the way to go, but all the instructions out there (even on the plugin repository sites) are out of date or don&#8217;t completely work or only work on Rails 1.2.x.  In this tutorial, however, we&#8217;ll go step-by-step to install a complete RESTful authentication suite with all the trimmings your advanced Rails 2.0 application requires.  Best of all, we&#8217;ll maintain complete source control of our user administration code.</p>
<p>Please note that the code in this tutorial is borrowed from a <a href="http://www.railsforum.com/viewtopic.php?id=14216" title="Code copied from this rails forum post" target="_blank">railsforum.com post</a> by a very smart user named &#8220;activefx&#8221;.  activefx has miraculously put together his research on Rick Olson&#8217;s brilliant <a href="http://technoweenie.stikipad.com/plugins/show/RESTful+authentication" target="_blank">restful_authentication plugin</a> to create a pretty robust user authentication process.  This post is just a bit more tailored for my Rails <a href="http://en.wikipedia.org/wiki/Model-view-controller" title="Wikipedia definition of MVC architectural patterns" target="_blank">MVC</a>+ architectural approach, which is to 1) install my plugins (if any), 2) use the Rails generators to generate the resources I think I&#8217;ll need, 3) generate my database migrations, add 4) my models (and library modules, if any), then 5) my controllers, and finally 6) my views.  This tutorial has also been reorganized and optimized for quick availability to copy and paste into new Ruby on Rails projects.</p>
<p><span id="more-1"></span>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
<strong># PLUGIN INSTALLATION</strong><br />
# To start, add the techno-weenie plugin repository to your local resource list,<br />
# then install restful_athentication plugin into your rails application.</p>
<p># in terminal:<strong> cd ~/my/rails/application/root</strong></p>
<blockquote><p>script/plugin source <a href="http://svn.techno-weenie.net/projects/plugins" title="restful_authentication repository" target="_blank">http://svn.techno-weenie.net/projects/plugins</a><br />
script/plugin install restful_authentication</p></blockquote>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
<strong># GENERATORS</strong><br />
# The restful_authentication plugin will generate our &#8220;<strong>User&#8221;</strong> model, controller, and view,<br />
# as well as our <strong>&#8220;Sessions&#8221;</strong> controller and view (no Session model needed).<br />
# We&#8217;ll create the models, controllers, and views for 1 new resource: <strong>&#8220;Roles&#8221;</strong><br />
# Then we&#8217;ll create 1 new join model for: <strong>&#8220;Permissions&#8221;</strong><br />
# Then we&#8217;ll create 2 new controllers: <strong>&#8220;Passwords&#8221;</strong> and <strong>&#8220;UserAccounts&#8221;</strong></p>
<blockquote><p>script/generate authenticated user sessions - -include-activation<br />
script/generate resource Role<br />
script/generate model Permission<br />
script/generate controller Passwords<br />
script/generate controller UserAccounts</p></blockquote>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
<strong># ROUTES</strong><br />
# Call me crazy, but I like to &#8220;map&#8221; out  my application routes before I start coding my MCV architecture.<br />
# This way I get a clearer sense of what Models, Controllers, and Views I&#8217;m going to need to configure.<br />
# I also get a more friendly, routes-related error message if I miss a section or<br />
# misspell a filename or something, instead of getting some puzzling error from the actual code.<br />
# In other words, at least I know the code is actually there or not before I start scratching my head.<br />
# (If you&#8217;re pre-rails, old school, or dyslexic: I&#8217;m speaking of the MVC paradigm that Rails employs.)<br />
# open file: <strong>config/routes.rb</strong></p>
<blockquote><p>ActionController::Routing::Routes.draw do |map|</p>
<p>map.root :controller =&gt; &#8220;sessions&#8221;, :action =&gt; &#8220;new&#8221;</p>
<p># begin restful_authentication routes &#8230;<br />
map.login  &#8216;/login&#8217;,  :controller =&gt; &#8217;sessions&#8217;, :action =&gt; &#8216;new&#8217;<br />
map.logout &#8216;/logout&#8217;, :controller =&gt; &#8217;sessions&#8217;, :action =&gt; &#8216;destroy&#8217;<br />
map.signup &#8216;/signup&#8217;, :controller =&gt; &#8216;users&#8217;, :action =&gt; &#8216;new&#8217;<br />
map.activate &#8216;/activate/:id&#8217;, :controller =&gt; &#8216;user_accounts&#8217;, :action =&gt; &#8217;show&#8217;<br />
map.change_password &#8216;/change_password&#8217;,   :controller =&gt; &#8216;user_accounts&#8217;, :action =&gt; &#8216;edit&#8217;<br />
map.forgot_password &#8216;/forgot_password&#8217;,   :controller =&gt; &#8216;passwords&#8217;, :action =&gt; &#8216;new&#8217;<br />
map.reset_password &#8216;/reset_password/:id&#8217;, :controller =&gt; &#8216;passwords&#8217;, :action =&gt; &#8216;edit&#8217;</p>
<p>map.resources :users, :member =&gt; { :enable =&gt; :put } do |users|<br />
users.resource :user_account<br />
users.resources :roles<br />
end</p>
<p>map.resource :session<br />
map.resource :password<br />
# &#8230; end restful_authentication routes</p>
<p># Install the default routes as the lowest priority.<br />
map.connect &#8216;:controller/:action/:id&#8217;<br />
map.connect &#8216;:controller/:action/:id.:format&#8217;</p>
<p>end</p></blockquote>
<p><strong><br />
</strong>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
<strong># DB MIGRATIONS</strong><br />
# As intelligent and agile developers, we&#8217;ve planned ahead<br />
# and already mapped out our application routes.<br />
# But before we can start working with our Rails models,<br />
# we need to generate our database migrations<br />
# so Rails can generate/update our database schema<br />
# when we run the &#8220;rake db:migrate&#8221; command afterwards.</p>
<p># open file: <strong>db/migrate/xxx_create_users.rb</strong></p>
<blockquote><p>class CreateUsers &lt; ActiveRecord::Migration<br />
def self.up<br />
create_table :users, :force =&gt; true do |t|<br />
t.string    :login<br />
t.string    :email<br />
t.string    :crypted_password, :limit =&gt; 40<br />
t.string    :salt, :limit =&gt; 40<br />
t.string    :remember_token<br />
t.datetime  :remember_token_expires_at<br />
t.string    :activation_code, :limit =&gt; 40<br />
t.datetime  :activated_at<br />
<strong>t.string    :password_reset_code, :limit =&gt; 40<br />
t.boolean   :enabled, :default =&gt; true<br />
t.integer    :updated_by</strong><br />
t.timestamps<br />
end<br />
end</p>
<p>def self.down<br />
drop_table :users<br />
end<br />
end</p></blockquote>
<p># open file: <strong>db/migrate/xxx_create_roles.rb</strong></p>
<blockquote><p>class CreateRoles &lt; ActiveRecord::Migration<br />
def self.up<br />
create_table :roles do |t|<br />
<strong>t.string :name</strong><br />
<strong>t.integer :updated_by</strong><br />
t.timestamps<br />
end<br />
end</p>
<p>def self.down<br />
drop_table :roles<br />
end<br />
end</p></blockquote>
<p># open file: <strong>db/migrate/xxx_create_permissions.rb</strong></p>
<blockquote><p>class CreatePermissions &lt; ActiveRecord::Migration<br />
def self.up<br />
create_table :permissions do |t|<br />
<strong>t.integer :role_id, :user_id, :null =&gt; false</strong><br />
<strong>t.integer :updated_by<br />
</strong> t.timestamps<br />
end</p>
<p><strong># Make sure the role migration file was generated first<br />
Role.create(:name =&gt; &#8217;super user&#8217;)<br />
# Then, add default admin user<br />
# Be sure change the password later or in this migration file<br />
user = User.new<br />
user.login = &#8220;super&#8221;<br />
user.email = &#8220;super@mydomain1.com&#8221;<br />
user.password = &#8220;password&#8221;<br />
user.password_confirmation = &#8220;password&#8221;<br />
user.save(false)<br />
user.send(:activate!)</strong></p>
<p><strong>role = Role.find_by_name(&#8217;super user&#8217;)<br />
user = User.find_by_login(&#8217;super&#8217;)</strong></p>
<p><strong>permission = Permission.new<br />
permission.role = role<br />
permission.user = user<br />
permission.save(false)</strong><br />
end</p>
<p>def self.down<br />
drop_table :permissions<br />
Role.find_by_name(&#8217;super user&#8217;).destroy<br />
User.find_by_login(&#8217;super&#8217;).destroy<br />
end<br />
end</p></blockquote>
<p># Now that we&#8217;ve created our database migrations, we&#8217;re ready to run our rake task<br />
# which will add our User, Role, and Permission models to our db</p>
<blockquote><p>rake db:migrate</p></blockquote>
<p><strong><br />
</strong>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
<strong># MODELS</strong><br />
# Now that we&#8217;ve created the main resources that we&#8217;re going to be working with,<br />
# we can start manipulating our models.<br />
# open file: <strong>app/models/role.rb</strong></p>
<blockquote><p>class Role &lt; ActiveRecord::Base<br />
has_many :permissions<br />
has_many :users, :through =&gt; :permissions<br />
end</p></blockquote>
<p># open file: <strong>app/models/permission.rb</strong></p>
<blockquote><p>class Permission &lt; ActiveRecord::Base<br />
belongs_to :user<br />
belongs_to :role<br />
end</p></blockquote>
<p># open file: <strong>app/models/user.rb</strong></p>
<blockquote><p>require &#8216;digest/sha1&#8242;<br />
class User &lt; ActiveRecord::Base<br />
# Virtual attribute for the unencrypted password<br />
attr_accessor :password</p>
<p>validates_presence_of     :login, :email<br />
validates_presence_of     :password,                   :if =&gt; :password_required?<br />
validates_presence_of     :password_confirmation,      :if =&gt; :password_required?<br />
validates_length_of       :password, :within =&gt; 4..40, :if =&gt; :password_required?<br />
validates_confirmation_of :password,                   :if =&gt; :password_required?<br />
validates_length_of       :login,    :within =&gt; 3..40<br />
validates_length_of       :email,    :within =&gt; 3..100<br />
validates_uniqueness_of   :login, :email, :case_sensitive =&gt; false<br />
validates_format_of       :email, :with =&gt; /(^([^@\s]+)@((?:[-_a-z0-9]+\.)+[a-z]{2,})$)|(^$)/i</p>
<p>has_many :permissions<br />
has_many :roles, :through =&gt; :permissions</p>
<p>before_save :encrypt_password<br />
before_create :make_activation_code</p>
<p># prevents a user from submitting a crafted form that bypasses activation<br />
# anything else you want your user to change should be added here.<br />
attr_accessible :login, :email, :password, :password_confirmation</p>
<p>class ActivationCodeNotFound &lt; StandardError; end<br />
class AlreadyActivated &lt; StandardError<br />
attr_reader :user, :message;<br />
def initialize(user, message=nil)<br />
@message, @user = message, user<br />
end<br />
end</p>
<p># Finds the user with the corresponding activation code, activates their account and returns the user.<br />
#<br />
# Raises:<br />
#  +User::ActivationCodeNotFound+ if there is no user with the corresponding activation code<br />
#  +User::AlreadyActivated+ if the user with the corresponding activation code has already activated their account<br />
def self.find_and_activate!(activation_code)<br />
raise ArgumentError if activation_code.nil?<br />
user = find_by_activation_code(activation_code)<br />
raise ActivationCodeNotFound if !user<br />
raise AlreadyActivated.new(user) if user.active?<br />
user.send(:activate!)<br />
user<br />
end</p>
<p>def active?<br />
# the presence of an activation date means they have activated<br />
!activated_at.nil?<br />
end</p>
<p># Returns true if the user has just been activated.<br />
def pending?<br />
@activated<br />
end</p>
<p># Authenticates a user by their login name and unencrypted password.  Returns the user or nil.<br />
# Updated 2/20/08<br />
def self.authenticate(login, password)<br />
u = find :first, :conditions =&gt; ['login = ?', login] # need to get the salt<br />
u &amp;&amp; u.authenticated?(password) ? u : nil<br />
end</p>
<p># Encrypts some data with the salt.<br />
def self.encrypt(password, salt)<br />
Digest::SHA1.hexdigest(&#8221;&#8211;#{salt}&#8211;#{password}&#8211;&#8221;)<br />
end</p>
<p># Encrypts the password with the user salt<br />
def encrypt(password)<br />
self.class.encrypt(password, salt)<br />
end</p>
<p>def authenticated?(password)<br />
crypted_password == encrypt(password)<br />
end</p>
<p>def remember_token?<br />
remember_token_expires_at &amp;&amp; Time.now.utc &lt; remember_token_expires_at<br />
end</p>
<p># These create and unset the fields required for remembering users between browser closes<br />
def remember_me<br />
remember_me_for 2.weeks<br />
end</p>
<p>def remember_me_for(time)<br />
remember_me_until time.from_now.utc<br />
end</p>
<p>def remember_me_until(time)<br />
self.remember_token_expires_at = time<br />
self.remember_token            = encrypt(&#8221;#{email}&#8211;#{remember_token_expires_at}&#8221;)<br />
save(false)<br />
end</p>
<p>def forget_me<br />
self.remember_token_expires_at = nil<br />
self.remember_token            = nil<br />
save(false)<br />
end</p>
<p>def forgot_password<br />
@forgotten_password = true<br />
self.make_password_reset_code<br />
end</p>
<p>def reset_password<br />
# First update the password_reset_code before setting the<br />
# reset_password flag to avoid duplicate email notifications.<br />
update_attribute(:password_reset_code, nil)<br />
@reset_password = true<br />
end</p>
<p># used in user_observer<br />
def recently_forgot_password?<br />
@forgotten_password<br />
end</p>
<p>def recently_reset_password?<br />
@reset_password<br />
end</p>
<p>def self.find_for_forget(email)<br />
find :first, :conditions =&gt; ['email = ? and activated_at IS NOT NULL', email]<br />
end</p>
<p>def has_role?(name)<br />
self.roles.find_by_name(name) ? true : false<br />
end</p>
<p><strong>protected</strong></p>
<p># before filter<br />
def encrypt_password<br />
return if password.blank?<br />
self.salt = Digest::SHA1.hexdigest(&#8221;&#8211;#{Time.now.to_s}&#8211;#{login}&#8211;&#8221;) if new_record?<br />
self.crypted_password = encrypt(password)<br />
end</p>
<p>def password_required?<br />
crypted_password.blank? || !password.blank?<br />
end</p>
<p>def make_activation_code<br />
self.activation_code = Digest::SHA1.hexdigest( Time.now.to_s.split(//).sort_by {rand}.join )<br />
end</p>
<p>def make_password_reset_code<br />
self.password_reset_code = Digest::SHA1.hexdigest( Time.now.to_s.split(//).sort_by {rand}.join )<br />
end</p>
<p><strong>private</strong></p>
<p>def activate!<br />
@activated = true<br />
self.update_attribute(:activated_at, Time.now.utc)<br />
end</p>
<p>end</p></blockquote>
<p># create file: <strong>app/models/user_mailer.rb</strong></p>
<blockquote><p>class UserMailer &lt; ActionMailer::Base<br />
def signup_notification(user)<br />
setup_email(user)<br />
@subject    += &#8216;Please activate your new account&#8217;<br />
@body[:url]  = &#8220;http://localhost:3000/activate/#{user.activation_code}&#8221;<br />
end</p>
<p>def activation(user)<br />
setup_email(user)<br />
@subject    += &#8216;Your account has been activated!&#8217;<br />
@body[:url]  = &#8220;http://localhost:3000/&#8221;<br />
end</p>
<p>def forgot_password(user)<br />
setup_email(user)<br />
@subject    += &#8216;You have requested to change your password&#8217;<br />
@body[:url]  = &#8220;http://localhost:3000/reset_password/#{user.password_reset_code}&#8221;<br />
end</p>
<p>def reset_password(user)<br />
setup_email(user)<br />
@subject    += &#8216;Your password has been reset.&#8217;<br />
end</p>
<p><strong>protected</strong><br />
def setup_email(user)<br />
@recipients  = &#8220;#{user.email}&#8221;<br />
@from        = &#8220;mail@mydomain1.com&#8221;<br />
@subject     = &#8220;mydomain1.com email setup&#8221;<br />
@sent_on     = Time.now<br />
@body[:user] = user<br />
end<br />
end</p></blockquote>
<p># create file: <strong>apps/models/user_observer.rb</strong></p>
<blockquote><p>class UserObserver &lt; ActiveRecord::Observer</p>
<p>def after_create(user)<br />
UserMailer.deliver_signup_notification(user)<br />
end</p>
<p>def after_save(user)<br />
UserMailer.deliver_activation(user) if user.pending?<br />
UserMailer.deliver_forgot_password(user) if user.recently_forgot_password?<br />
UserMailer.deliver_reset_password(user) if user.recently_reset_password?<br />
end</p>
<p>end</p></blockquote>
<p><strong><br />
</strong>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
<strong># CONFIGURATION</strong><br />
# Let&#8217;s quickly configure our smtp server and update our application environment<br />
# for use with restful_authentication:</p>
<p># create file: <strong>config/initializers/mail.rb</strong></p>
<blockquote><p># Email settings<br />
ActionMailer::Base.delivery_method = :smtp  # or :sendmail<br />
ActionMailer::Base.smtp_settings = {<br />
:address =&gt; &#8220;mail.domain.com&#8221;,<br />
:port =&gt; 25,<br />
:domain =&gt; &#8220;domain.com&#8221;,<br />
:authentication =&gt; :login,<br />
:user_name =&gt; &#8220;mail@domain.com&#8221;,<br />
:password =&gt; &#8220;uh&#8221;<br />
}</p></blockquote>
<p># open file: <strong>config/environment.rb</strong></p>
<blockquote><p>Rails::Initializer.run do |config|<br />
&#8230;<br />
config.active_record.observers = :user_observer<br />
&#8230;<br />
end</p></blockquote>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
<strong># AUTHENTICATED_SYSTEM LIBRARY MODULE<br />
</strong># Now that our models are setup, let&#8217;s update our<br />
# AuthenticatedSystem module with 6 new objects<br />
# 1) not_logged_in_required<br />
# 2) check_role<br />
# 3) check_super_user_role<br />
# 4) permission_denied<br />
# 5) store_referer<br />
# 6) redirect_to_referer_or_default</p>
<p># open file: <strong>lib/authenticated_system.rb</strong></p>
<blockquote><p>module AuthenticatedSystem<br />
protected<br />
# Returns true or false if the user is logged in.<br />
# Preloads @current_user with the user model if they&#8217;re logged in.<br />
def logged_in?<br />
!!current_user<br />
end</p>
<p># Accesses the current user from the session.<br />
# Future calls avoid the database because nil is not equal to false.<br />
def current_user<br />
@current_user ||= (login_from_session || login_from_basic_auth || login_from_cookie) unless @current_user == false<br />
end</p>
<p># Store the given user id in the session.<br />
def current_user=(new_user)<br />
session[:user_id] = new_user ? new_user.id : nil<br />
@current_user = new_user || false<br />
end</p>
<p># Check if the user is authorized<br />
#<br />
# Override this method in your controllers if you want to restrict access<br />
# to only a few actions or if you want to check if the user<br />
# has the correct rights.<br />
#<br />
# Example:<br />
#<br />
#  # only allow nonbobs<br />
#  def authorized?<br />
#    current_user.login != &#8220;bob&#8221;<br />
#  end<br />
def authorized?<br />
logged_in?<br />
end</p>
<p># Filter method to enforce a login requirement.<br />
#<br />
# To require logins for all actions, use this in your controllers:<br />
#<br />
#   before_filter :login_required<br />
#<br />
# To require logins for specific actions, use this in your controllers:<br />
#<br />
#   before_filter :login_required, :only =&gt; [ :edit, :update ]<br />
#<br />
# To skip this in a subclassed controller:<br />
#<br />
#   skip_before_filter :login_required<br />
#<br />
def login_required<br />
authorized? || access_denied<br />
end</p>
<p><strong># added<br />
def not_logged_in_required<br />
!logged_in? || permission_denied<br />
end</strong></p>
<p><strong># added<br />
def check_role(role)<br />
unless logged_in? &amp;&amp; @current_user.has_role?(role)<br />
if logged_in?<br />
permission_denied<br />
else<br />
store_referer<br />
access_denied<br />
end<br />
end<br />
end</strong></p>
<p><strong># added<br />
def check_super_user_role<br />
check_role(&#8217;super user&#8217;)<br />
end</strong></p>
<p># Redirect as appropriate when an access request fails.<br />
#<br />
# The default action is to redirect to the login screen.<br />
#<br />
# Override this method in your controllers if you want to have special<br />
# behavior in case the user is not authorized<br />
# to access the requested action.  For example, a popup window might<br />
# simply close itself.<br />
def access_denied<br />
respond_to do |format|<br />
format.html do<br />
store_location<br />
redirect_to new_session_path<br />
end<br />
format.any do<br />
request_http_basic_authentication &#8216;Web Password&#8217;<br />
end<br />
end<br />
end</p>
<p><strong># added<br />
def permission_denied<br />
respond_to do |format|<br />
format.html do<br />
#Put your domain name here ex. http://www.example.com<br />
domain_name = &#8220;http://localhost:3000&#8243;<br />
http_referer = session[:refer_to]<br />
if http_referer.nil?<br />
store_referer<br />
http_referer = ( session[:refer_to] || domain_name )<br />
end<br />
flash[:error] = &#8220;You don&#8217;t have permission to complete that action.&#8221;<br />
#The [0..20] represents the 21 characters in http://localhost:3000<br />
#You have to set that to the number of characters in your domain name<br />
if http_referer[0..20] != domain_name<br />
session[:refer_to] = nil<br />
redirect_to root_path<br />
else<br />
redirect_to_referer_or_default(root_path)<br />
end<br />
end<br />
format.xml do<br />
headers["Status"]           = &#8220;Unauthorized&#8221;<br />
headers["WWW-Authenticate"] = %(Basic realm=&#8221;Web Password&#8221;)<br />
render :text =&gt; &#8220;You don&#8217;t have permission to complete this action.&#8221;, :status =&gt; &#8216;401 Unauthorized&#8217;<br />
end<br />
end<br />
end</strong></p>
<p># Store the URI of the current request in the session.<br />
# We can return to this location by calling #redirect_back_or_default.<br />
def store_location<br />
session[:return_to] = request.request_uri<br />
end</p>
<p><strong># added<br />
def store_referer<br />
session[:refer_to] = request.env["HTTP_REFERER"]<br />
end</strong></p>
<p># Redirect to the URI stored by the most recent store_location call or<br />
# to the passed default.<br />
def redirect_back_or_default(default)<br />
redirect_to(session[:return_to] || default)<br />
session[:return_to] = nil<br />
end</p>
<p><strong># added<br />
def redirect_to_referer_or_default(default)<br />
redirect_to(session[:refer_to] || default)<br />
session[:refer_to] = nil<br />
end</strong></p>
<p># Inclusion hook to make #current_user and #logged_in?<br />
# available as ActionView helper methods.<br />
def self.included(base)<br />
base.send :helper_method, :current_user, :logged_in?<br />
end</p>
<p># Called from #current_user.  First attempt to login by the user id stored in the session.<br />
def login_from_session<br />
self.current_user = User.find_by_id(session[:user_id]) if session[:user_id]<br />
end</p>
<p># Called from #current_user.  Now, attempt to login by basic authentication information.<br />
def login_from_basic_auth<br />
authenticate_with_http_basic do |username, password|<br />
self.current_user = User.authenticate(username, password)<br />
end<br />
end</p>
<p># Called from #current_user.  Finaly, attempt to login by an expiring token in the cookie.<br />
def login_from_cookie<br />
user = cookies[:auth_token] &amp;&amp; User.find_by_remember_token(cookies[:auth_token])<br />
if user &amp;&amp; user.remember_token?<br />
cookies[:auth_token] = { :value =&gt; user.remember_token, :expires =&gt; user.remember_token_expires_at }<br />
self.current_user = user<br />
end<br />
end<br />
end</p></blockquote>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
<strong># CONTROLLERS</strong><br />
# Now that we&#8217;ve configured our Rails models, we&#8217;ll work on our Rails controllers</p>
<p># open file:</p>
<p><strong><br />
</strong># add this line to the ApplicationController class<strong><br />
</strong></p>
<blockquote><p># remember the file we just edited? this command is to include it here:<br />
include AuthenticatedSystem</p></blockquote>
<p># open file: <strong>app/controllers/users_controller.rb</strong></p>
<blockquote><p>class UsersController &lt; ApplicationController<br />
layout &#8216;application&#8217;<br />
before_filter :not_logged_in_required, :only =&gt; [:new, :create]<br />
before_filter :login_required, :only =&gt; [:show, :edit, :update]<br />
before_filter :check_super_user_role, :only =&gt; [:index, :destroy, :enable]</p>
<p>def index<br />
@users = User.find(:all)<br />
end</p>
<p># this show action only allows users to view their own profile<br />
def show<br />
@user = current_user<br />
end</p>
<p># render new.rhtml<br />
def new<br />
@user = User.new<br />
end</p>
<p>def create<br />
cookies.delete :auth_token<br />
@user = User.new(params[:user])<br />
@user.save!<br />
# Uncomment to have the user automatically<br />
# logged in after creating an account - Not Recommended<br />
# self.current_user = @user<br />
flash[:notice] = &#8220;Thanks for signing up! Please check your email to activate your account before logging in.&#8221;<br />
redirect_to login_path<br />
rescue ActiveRecord::RecordInvalid<br />
flash[:error] = &#8220;There was a problem creating your account.&#8221;<br />
render :action =&gt; &#8216;new&#8217;<br />
end</p>
<p>def edit<br />
@user = current_user<br />
end</p>
<p>def update<br />
@user = User.find(current_user)<br />
if @user.update_attributes(params[:user])<br />
flash[:notice] = &#8220;User updated&#8221;<br />
redirect_to :action =&gt; &#8217;show&#8217;, :id =&gt; current_user<br />
else<br />
render :action =&gt; &#8216;edit&#8217;<br />
end<br />
end</p>
<p>def destroy<br />
@user = User.find(params[:id])<br />
if @user.update_attribute(:enabled, false)<br />
flash[:notice] = &#8220;User disabled&#8221;<br />
else<br />
flash[:error] = &#8220;There was a problem disabling this user.&#8221;<br />
end<br />
redirect_to :action =&gt; &#8216;index&#8217;<br />
end</p>
<p>def enable<br />
@user = User.find(params[:id])<br />
if @user.update_attribute(:enabled, true)<br />
flash[:notice] = &#8220;User enabled&#8221;<br />
else<br />
flash[:error] = &#8220;There was a problem enabling this user.&#8221;<br />
end<br />
redirect_to :action =&gt; &#8216;index&#8217;<br />
end</p>
<p>def activate<br />
@user = User.find_by_activation_code(params[:id])<br />
if @user and @user.activate<br />
self.current_user = @user<br />
redirect_back_or_default(:controller =&gt; &#8216;/user_account&#8217;, :action =&gt; &#8216;index&#8217;)<br />
flash[:notice] = &#8220;Your account has been activated.&#8221;<br />
end<br />
redirect_to :action =&gt; &#8216;index&#8217;<br />
end</p>
<p>end</p></blockquote>
<p># open file: <strong>app/controllers/sessions_controller.rb</strong></p>
<blockquote><p># This controller handles the login/logout function of the site.<br />
class SessionsController &lt; ApplicationController<br />
layout &#8216;application&#8217;<br />
before_filter :login_required, :only =&gt; :destroy<br />
before_filter :not_logged_in_required, :only =&gt; [:new, :create]</p>
<p># render new.rhtml<br />
def new<br />
end</p>
<p>def create<br />
password_authentication(params[:login], params[:password])<br />
end</p>
<p>def destroy<br />
self.current_user.forget_me if logged_in?<br />
cookies.delete :auth_token<br />
reset_session<br />
flash[:notice] = &#8220;You have been logged out.&#8221;<br />
redirect_to login_path<br />
end</p>
<p>protected</p>
<p>def password_authentication(login, password)<br />
user = User.authenticate(login, password)<br />
if user == nil<br />
failed_login(&#8221;Your username or password is incorrect.&#8221;)<br />
elsif user.activated_at.blank?<br />
failed_login(&#8221;Your account is not active, please check your email for the activation code.&#8221;)<br />
elsif user.enabled == false<br />
failed_login(&#8221;Your account has been disabled.&#8221;)<br />
else<br />
self.current_user = user<br />
successful_login<br />
end<br />
end</p>
<p>private</p>
<p>def failed_login(message)<br />
flash.now[:error] = message<br />
render :action =&gt; &#8216;new&#8217;<br />
end</p>
<p>def successful_login<br />
if params[:remember_me] == &#8220;1&#8243;<br />
self.current_user.remember_me<br />
cookies[:auth_token] = { :value =&gt; self.current_user.remember_token , :expires =&gt; self.current_user.remember_token_expires_at }<br />
end<br />
flash[:notice] = &#8220;Logged in successfully&#8221;<br />
return_to = session[:return_to]<br />
if return_to.nil?<br />
redirect_to user_path(self.current_user)<br />
else<br />
redirect_to return_to<br />
end<br />
end</p>
<p>end</p></blockquote>
<p># open file: <strong>app/controllers/roles_controller.rb</strong></p>
<blockquote><p>class RolesController &lt; ApplicationController<br />
layout &#8216;application&#8217;<br />
before_filter :check_super_user_role</p>
<p>def index<br />
@user = User.find(params[:user_id])<br />
@all_roles = Role.find(:all)<br />
end</p>
<p>def update<br />
@user = User.find(params[:user_id])<br />
@role = Role.find(params[:id])<br />
unless @user.has_role?(@role.name)<br />
@user.roles &lt;&lt; @role<br />
end<br />
redirect_to :action =&gt; &#8216;index&#8217;<br />
end</p>
<p>def destroy<br />
@user = User.find(params[:user_id])<br />
@role = Role.find(params[:id])<br />
if @user.has_role?(@role.name)<br />
@user.roles.delete(@role)<br />
else<br />
redirect_to :action =&gt; &#8216;index&#8217;<br />
end</p>
<p>end</p></blockquote>
<p><strike># open file: <strong>app/controllers/permissions_controller.rb</strong></strike></p>
<blockquote><p># remember, there is no Permissions controller, just a Permission join model that links roles with users using the &#8220;has_many :y, :through =&gt; :z&#8221; relationship in both of those joined models.</p></blockquote>
<p># open file: <strong>app/controllers/passwords_controller.rb</strong></p>
<blockquote><p>class PasswordsController &lt; ApplicationController<br />
layout &#8216;application&#8217;<br />
before_filter :not_logged_in_required, :only =&gt; [:new, :create]</p>
<p># Enter email address to recover password<br />
def new<br />
end</p>
<p># Forgot password action<br />
def create<br />
return unless request.post?<br />
if @user = User.find_for_forget(params[:email])<br />
@user.forgot_password<br />
@user.save<br />
flash[:notice] = &#8220;A password reset link has been sent to your email address.&#8221;<br />
redirect_to login_path<br />
else<br />
flash[:notice] = &#8220;Could not find a user with that email address.&#8221;<br />
render :action =&gt; &#8216;new&#8217;<br />
end<br />
end</p>
<p># Action triggered by clicking on the /reset_password/:id link recieved via email<br />
# Makes sure the id code is included<br />
# Checks that the id code matches a user in the database<br />
# Then if everything checks out, shows the password reset fields<br />
def edit<br />
if params[:id].nil?<br />
render :action =&gt; &#8216;new&#8217;<br />
return<br />
end<br />
@user = User.find_by_password_reset_code(params[:id]) if params[:id]<br />
raise if @user.nil?<br />
rescue<br />
logger.error &#8220;Invalid Reset Code entered.&#8221;<br />
flash[:notice] = &#8220;Sorry - That is an invalid password reset code. Please check your code and try again. (Perhaps your email client inserted a carriage return?)&#8221;<br />
#redirect_back_or_default(&#8217;/')<br />
redirect_to new_user_path<br />
end</p>
<p># Reset password action /reset_password/:id<br />
# Checks once again that an id is included and makes sure that the password field isn&#8217;t blank<br />
def update<br />
if params[:id].nil?<br />
render :action =&gt; &#8216;new&#8217;<br />
return<br />
end<br />
if params[:password].blank?<br />
flash[:notice] = &#8220;Password field cannot be blank.&#8221;<br />
render :action =&gt; &#8216;edit&#8217;, :id =&gt; params[:id]<br />
return<br />
end<br />
@user = User.find_by_password_reset_code(params[:id]) if params[:id]<br />
raise if @user.nil?<br />
return if @user unless params[:password]<br />
if (params[:password] == params[:password_confirmation])<br />
#Uncomment and comment lines with @user to have the user logged in after reset - not recommended<br />
#self.current_user = @user #for the next two lines to work<br />
#current_user.password_confirmation = params[:password_confirmation]<br />
#current_user.password = params[:password]<br />
#@user.reset_password<br />
#flash[:notice] = current_user.save ? &#8220;Password reset&#8221; : &#8220;Password not reset&#8221;<br />
@user.password_confirmation = params[:password_confirmation]<br />
@user.password = params[:password]<br />
@user.reset_password<br />
flash[:notice] = @user.save ? &#8220;Password reset.&#8221; : &#8220;Password not reset.&#8221;<br />
else<br />
flash[:notice] = &#8220;Password mismatch.&#8221;<br />
render :action =&gt; &#8216;edit&#8217;, :id =&gt; params[:id]<br />
return<br />
end<br />
redirect_to login_path<br />
rescue<br />
logger.error &#8220;Invalid Reset Code entered&#8221;<br />
flash[:notice] = &#8220;Sorry - That is an invalid password reset code. Please check your code and try again. (Perhaps your email client inserted a carriage return?)&#8221;<br />
redirect_to new_user_path<br />
end</p>
<p>end</p></blockquote>
<p># open file: <strong>app/controllers/user_accounts_controller.rb</strong></p>
<blockquote><p>class UserAccountsController &lt; ApplicationController<br />
layout &#8216;application&#8217;<br />
before_filter :login_required, :except =&gt; :show<br />
before_filter :not_logged_in_required, :only =&gt; :show</p>
<p># Activate action<br />
def show<br />
# Uncomment and change paths to have user logged in after activation - not recommended<br />
#self.current_user = User.find_and_activate!(params[:id])<br />
User.find_and_activate!(params[:id])<br />
flash[:notice] = &#8220;Your account has been activated! You can now login.&#8221;<br />
redirect_to login_path<br />
rescue User::ArgumentError<br />
flash[:notice] = &#8216;Activation code not found. Please try creating a new account.&#8217;<br />
redirect_to new_user_path<br />
rescue User::ActivationCodeNotFound<br />
flash[:notice] = &#8216;Activation code not found. Please try creating a new account.&#8217;<br />
redirect_to new_user_path<br />
rescue User::AlreadyActivated<br />
flash[:notice] = &#8216;Your account has already been activated. You can log in below.&#8217;<br />
redirect_to login_path<br />
end</p>
<p>def edit<br />
end</p>
<p># Change password action<br />
def update<br />
return unless request.post?<br />
if User.authenticate(current_user.login, params[:old_password])<br />
if ((params[:password] == params[:password_confirmation]) &amp;&amp; !params[:password_confirmation].blank?)<br />
current_user.password_confirmation = params[:password_confirmation]<br />
current_user.password = params[:password]<br />
if current_user.save<br />
flash[:notice] = &#8220;Password successfully updated.&#8221;<br />
redirect_to root_path #profile_url(current_user.login)<br />
else<br />
flash[:error] = &#8220;An error occured, your password was not changed.&#8221;<br />
render :action =&gt; &#8216;edit&#8217;<br />
end<br />
else<br />
flash[:error] = &#8220;New password does not match the password confirmation.&#8221;<br />
@old_password = params[:old_password]<br />
render :action =&gt; &#8216;edit&#8217;<br />
end<br />
else<br />
flash[:error] = &#8220;Your old password is incorrect.&#8221;<br />
render :action =&gt; &#8216;edit&#8217;<br />
end<br />
end</p>
<p>end</p></blockquote>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
<strong># VIEWS<br />
</strong># To complete our MVC architecture, we&#8217;ll configure our application Views</p>
<p># open/create file: <strong>app/views/layouts/application.html.erb<br />
</strong># add this navigation as your eyes sees fit<strong><br />
</strong></p>
<blockquote><p>&lt;ul&gt;<br />
&lt;% if logged_in? %&gt;<br />
&lt;li&gt;Logged in as:&lt;/li&gt;<br />
&lt;li&gt;&lt;%= link_to h(current_user.login.capitalize), user_path(current_user) %&gt;&lt;/li&gt;<br />
&lt;ul&gt;<br />
&lt;li&gt;&lt;%= link_to &#8216;Edit Profile&#8217;, edit_user_path(current_user) %&gt;&lt;/li&gt;<br />
&lt;li&gt;&lt;%= link_to &#8216;Change Password&#8217;, change_password_path %&gt;&lt;/li&gt;<br />
&lt;li&gt;&lt;%= link_to &#8216;Log Out&#8217;, logout_url %&gt;&lt;/li&gt;<br />
&lt;/ul&gt;<br />
&lt;% if current_user.has_role?(&#8217;administrator&#8217;) %&gt;<br />
&lt;li&gt;&lt;%= link_to &#8216;Administer Users&#8217;, users_path %&gt;&lt;/li&gt;<br />
&lt;% end %&gt;<br />
&lt;% else %&gt;<br />
&lt;li&gt;&lt;%= link_to &#8216;Log In&#8217;, new_session_path %&gt;&lt;/li&gt;<br />
&lt;li&gt;&lt;%= link_to &#8216;Sign Up&#8217;, new_user_path %&gt;&lt;/li&gt;<br />
&lt;li&gt;&lt;%= link_to &#8216;Forgot Password?&#8217;, forgot_password_path %&gt;&lt;/li&gt;<br />
&lt;% end %&gt;<br />
&lt;/ul&gt;</p>
<p>&lt;%= yield %&gt;</p></blockquote>
<p># create file: <strong>app/views/roles/_role.html.erb</strong></p>
<blockquote><p>&lt;li&gt;<br />
&lt;%= role.name %&gt;<br />
&lt;% if @user.has_role?(role.name) %&gt;<br />
&lt;%= link_to &#8216;remove role&#8217;, user_role_url(:id =&gt; role.id, :user_id =&gt; @user.id), :method =&gt; :delete %&gt;<br />
&lt;% else %&gt;<br />
&lt;%= link_to &#8216;assign role&#8217;, user_role_url(:id =&gt; role.id, :user_id =&gt; @user.id), :method =&gt; :put %&gt;<br />
&lt;% end %&gt;<br />
&lt;/li&gt;</p></blockquote>
<p># create file: <strong>app/views/roles/index.html.erb </strong></p>
<blockquote><p>&lt;h2&gt;Roles for &lt;%=h @user.login.capitalize %&gt;&lt;/h2&gt;</p>
<p>&lt;h3&gt;Roles assigned:&lt;/h3&gt;<br />
&lt;ul&gt;&lt;%= render :partial =&gt; &#8216;role&#8217;, :collection =&gt; @user.roles %&gt;&lt;/ul&gt;</p>
<p>&lt;h3&gt;Roles available:&lt;/h3&gt;<br />
&lt;ul&gt;&lt;%= render :partial =&gt; &#8216;role&#8217;, :collection =&gt; (@all_roles - @user.roles) %&gt;&lt;/ul&gt;</p></blockquote>
<p># open file: <strong>app/views/sessions/new.html.erb</strong></p>
<blockquote><p>&lt;h2&gt;Login with User ID and Password:&lt;/h2&gt;</p>
<p>&lt;% form_tag session_path do %&gt;</p>
<p>&lt;p&gt;&lt;label for=&#8221;login&#8221;&gt;Login&lt;/label&gt;&lt;br/&gt;<br />
&lt;%= text_field_tag &#8216;login&#8217; %&gt;&lt;/p&gt;</p>
<p>&lt;p&gt;&lt;label for=&#8221;password&#8221;&gt;Password&lt;/label&gt;&lt;br /&gt;<br />
&lt;%= password_field_tag &#8216;password&#8217; %&gt;&lt;/p&gt;</p>
<p>&lt;p&gt;&lt;label for=&#8221;remember_me&#8221;&gt;Remember me:&lt;/label&gt;<br />
&lt;%= check_box_tag &#8216;remember_me&#8217; %&gt;&lt;/p&gt;</p>
<p>&lt;p&gt;&lt;%= submit_tag &#8216;Log in&#8217; %&gt;&lt;%= link_to &#8220;Sign Up&#8221;, new_user_path %&gt;&lt;/p&gt;<br />
&lt;% end %&gt;</p></blockquote>
<p># create file: <strong>app/views/users/_user.html.erb</strong></p>
<blockquote><p>&lt;tr class=&#8221;&lt;%= cycle(&#8217;odd&#8217;, &#8216;even&#8217;) %&gt;&#8221;&gt;<br />
&lt;td&gt;&lt;%=h user.login %&gt;&lt;/td&gt;<br />
&lt;td&gt;&lt;%=h user.email %&gt;&lt;/td&gt;<br />
&lt;td&gt;&lt;%= user.enabled ? &#8216;yes&#8217; : &#8216;no&#8217; %&gt;<br />
&lt;% unless user == current_user %&gt;<br />
&lt;% if user.enabled %&gt;<br />
&lt;%= link_to(&#8217;disable&#8217;, user_path(user.id), :method =&gt; :delete) %&gt;<br />
&lt;% else %&gt;<br />
&lt;%= link_to(&#8217;enable&#8217;, enable_user_path(user.id), :method =&gt; :put) %&gt;<br />
&lt;% end %&gt;<br />
&lt;% end %&gt;<br />
&lt;/td&gt;<br />
&lt;td&gt;&lt;%= link_to &#8216;edit roles&#8217;, user_roles_path(user) %&gt;]&lt;/td&gt;<br />
&lt;/tr&gt;</p></blockquote>
<p># create file: <strong>app/views/users/edit.html.erb</strong></p>
<blockquote><p>&lt;h2&gt;Edit Your Account&lt;/h2&gt;</p>
<p>&lt;p&gt;&lt;%= link_to &#8216;Show Profile&#8217;, user_path(@user) %&gt; | &lt;%= link_to &#8216;Change Password&#8217;, change_password_path %&gt;&lt;/p&gt;</p>
<p>&lt;%= error_messages_for :user %&gt;</p>
<p>&lt;% form_for :user, :url =&gt; user_url(@user), :html =&gt; { :method =&gt; :put } do |f| %&gt;<br />
&lt;p&gt;Email:&lt;br /&gt;&lt;%= f.text_field :email, :size =&gt; 60 %&gt;&lt;/p&gt;</p>
<p>&lt;%= submit_tag &#8216;Save&#8217; %&gt;<br />
&lt;% end %&gt;</p></blockquote>
<p># create file: <strong>app/views/users/index.html.erb</strong></p>
<blockquote><p>&lt;h2&gt;All Users&lt;/h2&gt;<br />
&lt;table&gt;<br />
&lt;tr&gt;<br />
&lt;th&gt;Username&lt;/th&gt;<br />
&lt;th&gt;Email&lt;/th&gt;<br />
&lt;th&gt;Enabled?&lt;/th&gt;<br />
&lt;th&gt;Roles&lt;/th&gt;<br />
&lt;/tr&gt;<br />
&lt;%= render :partial =&gt; &#8216;user&#8217;, :collection =&gt; @users %&gt;<br />
&lt;/table&gt;</p></blockquote>
<p># open file: <strong>app/views/users/new.html.erb</strong></p>
<blockquote><p># no necessary changes need to be made to this file at this time</p></blockquote>
<p># create file: <strong>app/views/users/show.html.erb</strong></p>
<blockquote><p>&lt;h2&gt;User: &lt;%=h @user.login %&gt;&lt;/h2&gt;<br />
&lt;p&gt;Joined on: &lt;%= @user.created_at.to_s(:long) %&gt;&lt;/p&gt;</p></blockquote>
<p># create folder: <strong>app/views/user_mailers</strong><br />
# create file: <strong>app/views/user_mailers/activation.html.erb</strong></p>
<blockquote><p>&lt;%=h @user.login %&gt;, your account has been activated.  To visit the site, follow the link below:</p>
<p>&lt;%= @url %&gt;</p></blockquote>
<p># create file: <strong>app/views/user_mailers/forgot_password.html.erb</strong></p>
<blockquote><p>&lt;%=h @user.login %&gt;, to reset your password, please visit</p>
<p>&lt;%= @url %&gt;</p></blockquote>
<p># create file: <strong>app/views/user_mailers/reset_password.html.erb</strong></p>
<blockquote><p>&lt;%=h @user.login %&gt;, your password has been reset.</p></blockquote>
<p># create file: <strong>app/views/user_mailers/signup_notification.html.erb</strong></p>
<blockquote><p>Your account has been created.</p>
<p>Username: &lt;%=h @user.login %&gt;</p>
<p>Visit this url to activate your account:</p>
<p>&lt;%= @url %&gt;</p></blockquote>
<p># create file: <strong>app/views/passwords/edit.html.erb </strong></p>
<blockquote><p>&lt;% form_tag url_for(:action =&gt; &#8220;update&#8221;, :id =&gt; params[:id]) do %&gt;</p>
<p>Password:&lt;br /&gt;<br />
&lt;%= password_field_tag :password %&gt;&lt;br /&gt;</p>
<p>Confirm Password:&lt;br /&gt;<br />
&lt;%= password_field_tag :password_confirmation %&gt;&lt;br /&gt;</p>
<p>&lt;%= submit_tag &#8220;Reset Your Password&#8221; %&gt;<br />
&lt;% end %&gt;</p></blockquote>
<p># create file: <strong>app/views/passwords/new.html.erb</strong></p>
<blockquote><p>&lt;h2&gt;Forgot Password&lt;/h2&gt;</p>
<p>&lt;% form_tag url_for(:action =&gt; &#8216;create&#8217;) do %&gt;</p>
<p>What is the email address used to create your account?&lt;br /&gt;<br />
&lt;%= text_field_tag :email, &#8220;&#8221;, :size =&gt; 50 %&gt;&lt;br /&gt;<br />
&lt;%= submit_tag &#8216;Reset Password&#8217; %&gt;<br />
&lt;% end %&gt;</p></blockquote>
<p># create file: <strong>app/views/user_accounts/edit.html.erb</strong></p>
<blockquote><p>&lt;% form_tag url_for(:action =&gt; &#8220;update&#8221;) do %&gt;</p>
<p>&lt;p&gt;&lt;label for=&#8221;old_password&#8221; class=&#8221;block&#8221;&gt;Old Password&lt;/label&gt;&lt;br /&gt;<br />
&lt;%= password_field_tag &#8216;old_password&#8217;, @old_password, :size =&gt; 45 %&gt;&lt;/p&gt;</p>
<p>&lt;p&gt;&lt;label for=&#8221;password&#8221; class=&#8221;block&#8221;&gt;New Password&lt;/label&gt;&lt;br /&gt;<br />
&lt;%= password_field_tag &#8216;password&#8217;, {}, :size =&gt; 45 %&gt;&lt;br /&gt;<br />
&lt;small&gt;Between 4 and 40 characters&lt;/small&gt;&lt;/p&gt;</p>
<p>&lt;p&gt;&lt;label for=&#8221;password_confirmation&#8221;  class=&#8221;block&#8221;&gt;Confirm new password&lt;/label&gt;&lt;br /&gt;<br />
&lt;%= password_field_tag &#8216;password_confirmation&#8217;, {}, :size =&gt; 45 %&gt;&lt;/p&gt;</p>
<p>&lt;%= submit_tag &#8216;Change password&#8217; %&gt;<br />
&lt;% end %&gt;</p></blockquote>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
<strong># Start &#8216;er up!</strong></p>
<blockquote><p>ruby script/server -p 3000</p></blockquote>
<p><strong># Done!</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://crazyrails.com/how-to-install-restful-authentication/feed/</wfw:commentRss>
		</item>
		<item>
		<title>How to install a Ruby on Rails 2.0 Redmine on Engines website</title>
		<link>http://crazyrails.com/how-to-install-redmine-engines-website/</link>
		<comments>http://crazyrails.com/how-to-install-redmine-engines-website/#comments</comments>
		<pubDate>Thu, 03 Apr 2008 18:09:57 +0000</pubDate>
		<dc:creator>Marty</dc:creator>
		
		<category><![CDATA[Linux]]></category>

		<category><![CDATA[Ruby on Rails]]></category>

		<category><![CDATA[cms]]></category>

		<category><![CDATA[engines]]></category>

		<category><![CDATA[plugins]]></category>

		<category><![CDATA[rails]]></category>

		<category><![CDATA[redmine]]></category>

		<guid isPermaLink="false">http://crazyrails.com/how-to-install-redmine-engines-website/</guid>
		<description><![CDATA[# on local machine
# check out a working copy of redmine from svn repository trunk
 cd ~/work
svn co http://redmine.rubyforge.org/svn/trunk ~/work/redmine_trunk
cd ~/work/redmine_trunk

# install engines plugin
# this will auto install to your railsapp/vendor/plugins/engines directory
script/plugin install http://svn.rails-engines.org/plugins/engines
# create a database.yml file
 nano config/database.yml
see database.yml for sqlite3 file
# migrate the database using rake task
 rake db:migrate RAILS_ENV=production
rake db:migrate RAILS_ENV=development
# [...]]]></description>
			<content:encoded><![CDATA[<p># on local machine<br />
# check out a working copy of redmine from svn repository trunk</p>
<blockquote><p> cd ~/work<br />
svn co http://redmine.rubyforge.org/svn/trunk ~/work/redmine_trunk<br />
cd ~/work/redmine_trunk</p></blockquote>
<p><span id="more-7"></span></p>
<p># install engines plugin<br />
# this will auto install to your railsapp/vendor/plugins/engines directory</p>
<blockquote><p>script/plugin install http://svn.rails-engines.org/plugins/engines</p></blockquote>
<p># create a database.yml file</p>
<blockquote><p> nano config/database.yml<br />
see <a href="http://crazyrails.com/wp-content/uploads/2008/04/database.yml" target="_blank" title="database.yml for sqlite3">database.yml for sqlite3</a> file</p></blockquote>
<p># migrate the database using rake task</p>
<blockquote><p> rake db:migrate RAILS_ENV=production<br />
rake db:migrate RAILS_ENV=development</p></blockquote>
<p># load default redmine data</p>
<blockquote><p> rake redmine:load_default_data RAILS_ENV=production<br />
rake redmine:load_default_data RAILS_ENV=development</p></blockquote>
<p># start local mongrel/webrick servers to test the installation</p>
<blockquote><p> ruby script/server -e production -p 3000<br />
ruby script/server -e development -p 3001</p></blockquote>
<p># in web browser, navigate to both &#8220;production&#8221; server and &#8220;development&#8221; server</p>
<blockquote><p> <a href="http://localhost:3000/" target="_blank">http://localhost:3000/</a><br />
<a href="http://localhost:3001/" target="_blank">http://localhost:3001/</a></p></blockquote>
<p># log in to redmine as administrator</p>
<blockquote><p> username: <strong>admin</strong><br />
password: <strong>admin</strong></p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://crazyrails.com/how-to-install-redmine-engines-website/feed/</wfw:commentRss>
		</item>
		<item>
		<title>How to setup a Linux web server using the command line, Part 6 : Mongrel Clusters</title>
		<link>http://crazyrails.com/how-to-setup-a-linux-web-server-using-the-command-line-part-6-mongrel-clusters/</link>
		<comments>http://crazyrails.com/how-to-setup-a-linux-web-server-using-the-command-line-part-6-mongrel-clusters/#comments</comments>
		<pubDate>Thu, 03 Apr 2008 17:05:42 +0000</pubDate>
		<dc:creator>Marty</dc:creator>
		
		<category><![CDATA[Linux]]></category>

		<category><![CDATA[Ruby on Rails]]></category>

		<category><![CDATA[clusters]]></category>

		<category><![CDATA[mongrels]]></category>

		<guid isPermaLink="false">http://crazyrails.com/how-to-setup-a-linux-web-server-using-the-command-line-part-5-mongrel-clusters-with-apache/</guid>
		<description><![CDATA[#
# Configuring and Administering Mongrel Clusters for your Rails Sites
#
Now that we have our Rails site&#8217;s vhost setup and enabled in Apache server, and perhaps we&#8217;ve enabled our site with Subversion and Capistrano, we can create a Mongrel Cluster configuration to run the wonderful Ruby code we&#8217;ve written.  We definitely want our Mongrel Cluster to [...]]]></description>
			<content:encoded><![CDATA[<p>#<br />
# Configuring and Administering Mongrel Clusters for your Rails Sites<br />
#</p>
<p>Now that we have our Rails site&#8217;s vhost setup and enabled in Apache server, and perhaps we&#8217;ve enabled our site with Subversion and Capistrano, we can create a Mongrel Cluster configuration to run the wonderful Ruby code we&#8217;ve written.  We definitely want our Mongrel Cluster to startup when the server reboots, and if we&#8217;ve capified our application with Capistrano in <a href="http://crazyrails.com/how-to-setup-a-linux-web-server-using-the-command-line-part-5-capistrano-deployment/" title="Part 5: Deploying with Capistrano">Part 5</a>, we&#8217;ll want Capistrano to be able to restart our Mongrel Cluster after deploying a new version of our application.</p>
<p><span id="more-16"></span><strong># on remote server</strong></p>
<p># configure rails application&#8217;s mongrel cluster (into application root directory!!!)<br />
# make sure to set the correct port number (-p) and number of mongrels (-N)</p>
<blockquote><p># capistrano sites use the &#8220;/current&#8221; directory as their root<br />
mongrel_rails cluster::configure -e production -p 8000 -N 2 -c /home/super/public_html/mydomain1.com/current -a 127.0.0.1</p>
<p># or if you&#8217;re not using capistrano, your config command may be<br />
mongrel_rails cluster::configure -e production -p 8000 -N 2 -c /home/super/public_html/mydomain1.com -a 127.0.0.1</p></blockquote>
<p># start mongrel_cluster</p>
<blockquote><p>mongrel_rails cluster::start</p></blockquote>
<p># configure mongrel_cluster autostart on reboot (once for server)</p>
<blockquote><p># copy mongrel_cluster resource to startup (init.d) directory<br />
sudo cp /usr/lib/ruby/gems/1.8/gems/mongrel_cluster-1.0.5/resources/mongrel_cluster /etc/init.d/</p>
<p># set executable permissions on the mongrel_cluster startup resource<br />
sudo chmod +x /etc/init.d/mongrel_cluster</p>
<p># update rc.local boot file<br />
sudo /usr/sbin/update-rc.d -f mongrel_cluster defaults</p>
<p># make sure symlink is in place for working ruby installation<br />
sudo ln -s /usr/bin/ruby1.8 /usr/bin/ruby</p>
<p># add mongrel user and add to www-data group<br />
sudo useradd mongrel<br />
sudo usermod -a -G www-data mongrel</p></blockquote>
<p># create symlink for your mongrel_cluster.yml so it survives reboots (for each site/vhost)</p>
<blockquote><p> # make directory for mongrel cluster settings<br />
sudo mkdir /etc/mongrel_cluster</p>
<p># capistrano users<br />
sudo ln -s /home/super/public_html/mydomain1.com/current/config/mongrel_cluster.yml /etc/mongrel_cluster/mydomain1.com.yml</p>
<p># non-capistrano users<br />
sudo ln -s /home/super/public_html/mydomain1.com/config/mongrel_cluster.yml /etc/mongrel_cluster/mydomain1.com.yml</p></blockquote>
<p># <strong>Subversion and Capistrano users:</strong> At this point, you&#8217;ll want to make a copy of the &#8220;config/mongrel_cluster.yml&#8221; file into your local working copy, commit it to svn, and &#8220;cap deploy&#8221; your application so it is regenerated in a new capistrano &#8220;release&#8221;. For example, on your <strong>local machine</strong>:</p>
<blockquote><p># navigate to your local working copy root<br />
cd ~/work/myproject1_trunk</p>
<p># create a new file, and copy-paste from remote file<br />
nano config/mongrel_cluster.yml</p>
<p># commit the new file to subversion<br />
svn add config/mongrel_cluster.yml<br />
svn commit -m &#8220;added mongrel cluster config file&#8221;</p>
<p># deploy your changes with capistrano<br />
cap deploy</p></blockquote>
<p># <strong>Subversion and Capistrano users:</strong> Now back to your <strong>remote server</strong> and continue&#8230;</p>
<p># control mongrel_clusters (from your application root directory!!!)</p>
<blockquote><p>cd ~/public_html/mydomain1.com/current</p>
<p>mongrel_rails cluster::status<br />
mongrel_rails cluster::stop<br />
mongrel_rails cluster::start<br />
mongrel_rails cluster::restart</p>
<p># and<br />
mongrel_cluster_ctl status<br />
mongrel_cluster_ctl stop<br />
mongrel_cluster_ctl start<br />
mongrel_cluster_ctl restart</p></blockquote>
<p># now let&#8217;s make sure your site is enabled in apache</p>
<blockquote><p>ls /etc/apache2/sites-enabled<br />
# if you don&#8217;t see &#8220;mydomain1.com&#8221; listed, enable it<br />
sudo a2ensite mydomain1.com</p></blockquote>
<p># (re)start apache server</p>
<blockquote><p>sudo /etc/init.d/apache2 start<br />
# or<br />
sudo /etc/init.d/apache2 reload</p></blockquote>
<p><strong>Done!</strong></p>
<p>Now you should be able to reboot your remote server and see your apache2-enabled, mongrel_cluster-riding, subversion-tracked, and capistrano-deployed websites from a web browser</p>
<blockquote><p>http://mydomain1.com<br />
http://mydomain2.net<br />
http://mydomain3.ws<br />
# secure versions (self-signed)<br />
https://mydomain1.com<br />
https://mydomain2.net<br />
https://mydomain3.ws</p></blockquote>
<p><strong>Really done!</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://crazyrails.com/how-to-setup-a-linux-web-server-using-the-command-line-part-6-mongrel-clusters/feed/</wfw:commentRss>
		</item>
		<item>
		<title>How to setup a Linux web server using the command line, Part 5 : Capistrano Deployment</title>
		<link>http://crazyrails.com/how-to-setup-a-linux-web-server-using-the-command-line-part-5-capistrano-deployment/</link>
		<comments>http://crazyrails.com/how-to-setup-a-linux-web-server-using-the-command-line-part-5-capistrano-deployment/#comments</comments>
		<pubDate>Thu, 03 Apr 2008 17:02:02 +0000</pubDate>
		<dc:creator>Marty</dc:creator>
		
		<category><![CDATA[Linux]]></category>

		<category><![CDATA[Ruby on Rails]]></category>

		<category><![CDATA[automation]]></category>

		<category><![CDATA[capistrano]]></category>

		<category><![CDATA[Subversion]]></category>

		<guid isPermaLink="false">http://crazyrails.com/how-to-setup-a-linux-web-server-using-the-command-line-part-5-capistrano-deployment/</guid>
		<description><![CDATA[#
# Capistrano setup for Subversion+Capistrano Web Applications
#
Honestly, our days are done with uploading program changes one file at a time, so let&#8217;s automate the whole svn commit and application deployment process with an easy-to-use ruby gem called Capistrano.  After we &#8220;capify&#8221; our application, we&#8217;ll be able to deploy our application to the remote server with [...]]]></description>
			<content:encoded><![CDATA[<p>#<br />
# Capistrano setup for Subversion+Capistrano Web Applications<br />
#</p>
<p>Honestly, our days are done with uploading program changes one file at a time, so let&#8217;s automate the whole svn commit and application deployment process with an easy-to-use ruby gem called Capistrano.  After we &#8220;capify&#8221; our application, we&#8217;ll be able to deploy our application to the remote server with a simple &#8220;cap deploy&#8221; command.  Capistrano will also take care of the svn commit process for the new application release/revision.  We&#8217;ll still use Subversion for our day-to-day revision commitals, as we do in <a href="http://crazyrails.com/how-to-setup-a-linux-web-server-using-the-command-line-part-4-subversion-setup/" title="Part 4: Subversion Setup">Part 4</a>, but it&#8217;s nice that Capistrano handles a new svn commit upon deployment.</p>
<p><span id="more-17"></span></p>
<p><strong># on local machine</strong></p>
<p># navigate to your working copy</p>
<blockquote><p>cd ~/work/myproject1</p></blockquote>
<p># capify working copy</p>
<blockquote><p>capify .</p></blockquote>
<p># edit generated config/deploy.rb file</p>
<blockquote><p>nano config/deploy.rb<br />
see <a href="http://crazyrails.com/wp-content/uploads/2008/04/cap_config_deploy_local.txt" class="attachmentlink" target="_blank">cap_config_deploy_local.txt</a> file</p></blockquote>
<p># capistrano needs to write some files to the server</p>
<blockquote><p>cap deploy:setup</p></blockquote>
<p># commit capification to svn</p>
<blockquote><p>svn status<br />
svn add Capfile<br />
svn add config/deploy.rb<br />
svn commit -m &#8220;capified with capistrano&#8221;</p></blockquote>
<p># rails users: setup a script/spin file<br />
# so capistrano may restart mongrels and mongrel clusters</p>
<blockquote><p>touch script/spin<br />
nano script/spin<br />
# add one line:<br />
&#8212;&#8212;-<br />
/home/super/public_html/mydomain1.com/current/script/process/spawner -p 8000 -i 2 -e production<br />
&#8212;&#8212;-</p></blockquote>
<p># add script/spin file and commit to svn</p>
<blockquote><p>svn add script/spin<br />
svn commit -m &#8220;added capistrano&#8217;s script/spin mongrel restart file&#8221;</p></blockquote>
<p># propset script/spin file and commit to svn</p>
<blockquote><p>svn propset svn:executable on script/spin<br />
svn commit -m &#8220;propset script/spin file as executable for subversion&#8221;</p></blockquote>
<p># run some tests to make sure capistrano can deploy</p>
<blockquote><p>cap deploy:migrate<br />
cap deploy:cold</p></blockquote>
<p># deploy your application for real!</p>
<blockquote><p>cap deploy</p></blockquote>
<p># make changes in some file content</p>
<blockquote><p>cd ~/work/corext_work</p></blockquote>
<p># when done</p>
<blockquote><p>svn add &#8211;force .<br />
svn commit -m &#8220;import some new changes&#8221;<br />
cap deploy</p></blockquote>
<p><strong>Done!</strong></p>
<p>Now on to <a href="http://crazyrails.com/how-to-setup-a-linux-web-server-using-the-command-line-part-6-mongrel-clusters/" title="Part 6: Mongrel Cluster Configuration">Part 6</a> where we configure and start our mongrel clusters for our Ruby on Rails Web 2.0 applications&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://crazyrails.com/how-to-setup-a-linux-web-server-using-the-command-line-part-5-capistrano-deployment/feed/</wfw:commentRss>
		</item>
		<item>
		<title>How to setup a Linux web server using the command line, Part 4 : Subversion Repository Setup</title>
		<link>http://crazyrails.com/how-to-setup-a-linux-web-server-using-the-command-line-part-4-subversion-setup/</link>
		<comments>http://crazyrails.com/how-to-setup-a-linux-web-server-using-the-command-line-part-4-subversion-setup/#comments</comments>
		<pubDate>Thu, 03 Apr 2008 15:41:03 +0000</pubDate>
		<dc:creator>Marty</dc:creator>
		
		<category><![CDATA[Linux]]></category>

		<category><![CDATA[Ruby on Rails]]></category>

		<category><![CDATA[Subversion]]></category>

		<guid isPermaLink="false">http://crazyrails.com/how-to-setup-a-linux-web-server-using-the-command-line-part-4-subversion-setup/</guid>
		<description><![CDATA[#
# svn setup for Subversion+Capistrano Web Applications
#
If we&#8217;re going to be agile developers, we&#8217;ll want to employ Subversion and Capistrano to track versions and deploy our applications quickly.  Let&#8217;s setup a base repository for subversion to call home.  Then let&#8217;s create an svn repository shell for our project, which we&#8217;ll deploy with Capistrano in Part [...]]]></description>
			<content:encoded><![CDATA[<p>#<br />
# svn setup for Subversion+Capistrano Web Applications<br />
#</p>
<p>If we&#8217;re going to be agile developers, we&#8217;ll want to employ Subversion and Capistrano to track versions and deploy our applications quickly.  Let&#8217;s setup a base repository for subversion to call home.  Then let&#8217;s create an svn repository shell for our project, which we&#8217;ll deploy with Capistrano in <a href="http://crazyrails.com/how-to-setup-a-linux-web-server-using-the-command-line-part-5-capistrano-deployment/" title="Part 5: Deploying with Capistrano">Part 5</a>.  But first, go through these steps for each website&#8217;s apache vhost you&#8217;ve created in <a href="http://crazyrails.com/how-to-setup-a-linux-web-server-using-the-command-line-part-3-apache-vhosts/" title="Part 3: Apache Vhosts">Part 3</a>.</p>
<p><span id="more-10"></span><br />
<strong># on remote server</strong></p>
<p># create repositories base</p>
<blockquote><p>mkdir -p /home/super/rep/{svn,crm,git}</p></blockquote>
<p># create svn project repositories</p>
<blockquote><p>svnadmin create /home/super/rep/svn/myproject1</p></blockquote>
<p># create standard svn skeleton project</p>
<blockquote><p>svn mkdir &#8220;file:///home/super/rep/svn/myproject1/branches&#8221; &#8220;file:///home/super/rep/svn/myproject1/tags&#8221; &#8220;file:///home/super/rep/svn/myproject1/trunk&#8221; -m &#8220;project start&#8221;</p>
<p># output<br />
&gt; Committed revision 1.</p></blockquote>
<p><strong># on local machine</strong></p>
<p># config ssh connection for svn</p>
<blockquote><p>nano ~/.subversion/config<br />
# add under [tunnels]<br />
my_ssh = /usr/bin/ssh -p 33333 -l super</p></blockquote>
<p># checkout a working copy</p>
<blockquote><p>svn co svn+my_ssh://111.222.333.444/home/super/rep/svn/myproject1/trunk ~/work/myproject1_work<br />
# you should see output like this<br />
Checked out revision 1.</p></blockquote>
<p># the above svn checkout command places the svn working copy in the (hidden) directory &#8220;.svn&#8221;.  To see this hidden folder, type:</p>
<blockquote><p>ls -a ~/work/myproject1_work</p></blockquote>
<p><strong># Cool. Now we have a bare-bones working copy so we can start or import our rails application(s)</strong></p>
<p># change directory to working copy root</p>
<blockquote><p>cd ~/work/myproject1_work</p></blockquote>
<p># ignore certain files and folders</p>
<blockquote><p>svn propset svn:ignore &#8220;*&#8221; log/<br />
svn propset svn:ignore &#8220;*&#8221; tmp/<br />
svn commit -m &#8220;set to ignore tmp/ and log/ directories&#8221;</p></blockquote>
<p># now you can make changes in the file content under</p>
<blockquote><p>cd ~/work/myproject1_work</p></blockquote>
<p># when you come to a stopping point, you can force svn to add all the changes you&#8217;ve made<br />
# to your application and commit them to the remote repository.</p>
<blockquote><p>svn add &#8211;force .<br />
svn commit -m &#8220;import some new changes&#8221;</p></blockquote>
<p><strong>Done!</strong></p>
<p>Now on to <a href="http://crazyrails.com/how-to-setup-a-linux-web-server-using-the-command-line-part-5-capistrano-deployment/" title="Part 5: Deploying with Capistrano">Part 5</a> where we&#8217;ll capify our working copy for use with Capistrano, a very simple to use, automated web application deployment gem&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://crazyrails.com/how-to-setup-a-linux-web-server-using-the-command-line-part-4-subversion-setup/feed/</wfw:commentRss>
		</item>
		<item>
		<title>How to setup a Linux web server using the command line, Part 3 : Apache Vhosts</title>
		<link>http://crazyrails.com/how-to-setup-a-linux-web-server-using-the-command-line-part-3-apache-vhosts/</link>
		<comments>http://crazyrails.com/how-to-setup-a-linux-web-server-using-the-command-line-part-3-apache-vhosts/#comments</comments>
		<pubDate>Thu, 03 Apr 2008 13:20:01 +0000</pubDate>
		<dc:creator>Marty</dc:creator>
		
		<category><![CDATA[Linux]]></category>

		<category><![CDATA[Ruby on Rails]]></category>

		<category><![CDATA[apache]]></category>

		<category><![CDATA[installation]]></category>

		<category><![CDATA[rails]]></category>

		<category><![CDATA[vhosts]]></category>

		<guid isPermaLink="false">http://crazyrails.com/how-to-setup-a-linux-web-server-using-the-command-line-part-3-apache-vhosts-subversion-and-capistrano/</guid>
		<description><![CDATA[#
# Create Apache Vhosts for Subversion+Capistrano Web Applications
#
Back in Part 2, we installed our Web 2.0 server applications.  Let&#8217;s continue our Linux web server setup by installing some Web 2.0 sites.  Web application sites are handled in apache2 server by setting up vhosts, or virtual hosts.  Virtual hosts allow you to setup your websites the [...]]]></description>
			<content:encoded><![CDATA[<p>#<br />
# Create Apache Vhosts for Subversion+Capistrano Web Applications<br />
#</p>
<p>Back in <a href="http://crazyrails.com/how-to-setup-a-linux-web-server-using-the-command-line-part-2-installing-applications/" title="Part 2: Install Web 2.0 Applications">Part 2</a>, we installed our Web 2.0 server applications.  Let&#8217;s continue our Linux web server setup by installing some Web 2.0 sites.  Web application sites are handled in apache2 server by setting up vhosts, or virtual hosts.  Virtual hosts allow you to setup your websites the way you want, all from a text config file that&#8217;s easy to create and make changes to.<strong><br />
</strong><br />
<span id="more-9"></span><strong># on remote server</strong></p>
<p># create apache vhost config for each web application site</p>
<blockquote><p>sudo nano /etc/apache2/sites-available/mydomain1.com<br />
# see <a href="http://crazyrails.com/wp-content/uploads/2008/04/apache2_sites-available_mydomain1.com" target="_blank" title="apache2_sites-available_mydomain1.com">apache2_sites-available_mydomain1.com</a> file</p>
<p>sudo nano /etc/apache2/sites-available/mydomain2.net<br />
# see <a href="http://crazyrails.com/wp-content/uploads/2008/04/apache2_sites-available_mydomain2.net" target="_blank" title="apache2_sites-available_mydomain2.net">apache2_sites-available_mydomain2.net</a> file</p>
<p>sudo nano /etc/apache2/sites-available/mydomain3.ws<br />
# see <a href="http://crazyrails.com/wp-content/uploads/2008/04/apache2_sites-available_mydomain3.ws" target="_blank" title="apache2_sites-available_mydomain3.ws">apache2_sites-available_mydomain3.ws</a> file</p></blockquote>
<p># create self-signed ssl certificates</p>
<blockquote><p>sudo make-ssl-cert /usr/share/ssl-cert/ssleay.cnf /etc/ssl/certs/mydomain1.com.pem</p>
<p>sudo make-ssl-cert /usr/share/ssl-cert/ssleay.cnf /etc/ssl/certs/mydomain2.net.pem</p>
<p>sudo make-ssl-cert /usr/share/ssl-cert/ssleay.cnf /etc/ssl/certs/mydomain3.ws.pem</p></blockquote>
<p># create web server&#8217;s public root directory as super</p>
<blockquote><p>mkdir /home/super/public_html<br />
#chown -R super:super /home/super/public_html</p></blockquote>
<p><strong>Done!</strong></p>
<p>Now on to <a href="http://crazyrails.com/how-to-setup-a-linux-web-server-using-the-command-line-part-4-subversion-setup/" title="Part 4: Subversion Setup">Part 4</a> where we setup a subversion repository for each of these apache vhosts we&#8217;ve setup&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://crazyrails.com/how-to-setup-a-linux-web-server-using-the-command-line-part-3-apache-vhosts/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
