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

<channel>
	<title>Romtex Limited</title>
	<atom:link href="http://romtex.co.uk/feed/" rel="self" type="application/rss+xml" />
	<link>http://romtex.co.uk</link>
	<description>The official website of Romtex Limited</description>
	<pubDate>Wed, 18 Jun 2008 12:50:04 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.7.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>models</title>
		<link>http://romtex.co.uk/2007/11/27/models/</link>
		<comments>http://romtex.co.uk/2007/11/27/models/#comments</comments>
		<pubDate>Tue, 27 Nov 2007 19:50:44 +0000</pubDate>
		<dc:creator>Romtex</dc:creator>
		
		<category><![CDATA[rails]]></category>

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

		<guid isPermaLink="false">http://romtex.co.uk/2007/11/27/models/</guid>
		<description><![CDATA[Rails&#8217; design provides for a complete implementation of the Model-View-Controller (MVC) pattern.  The model element in particular is implemented as a self-contained layer responsible for all interactions with the data storage sub system.  As such the model offers the logically correct place to implement all business rules related to the correct handling of [...]]]></description>
			<content:encoded><![CDATA[<br/>
<p>Rails&#8217; design provides for a complete implementation of the Model-View-Controller (MVC) pattern.  The model element in particular is implemented as a self-contained layer responsible for all interactions with the data storage sub system.  As such the model offers the logically correct place to implement all business rules related to the correct handling of data throughout the application.</p>
<p>A well developed and tested model gives a great comfort and luxury that guarantees that whatever view-controller is put over the top, or how it is implemented, the integrity of the database with its respect for all business rules is complete and guaranteed.</p>
<span id="more-16"></span>
<p>This sounds like a bit of mouthful but is in fact very easy to implement.  There is not actually very much that needs to go into a model therefore it is quite simple to ensure it is correct.</p>
<h4>associations</h4>
<p class="indent">Models define the relationships with other models.  For example given a one-to-many relationship between groups and users (a group contains many users, a user belongs to exactly one group) requires the following associations:</p>
<pre class="indent">class Group &lt; ActiveRecord::Base
  has_many :users
end
		
class User &lt; ActiveRecord::Base
  belongs_to :group
end</pre>
<h4>validation</h4>
<p class="indent">Having all validation in the model is very powerful as a correct model guarantees complete correctness within the database.  Rails contains a number of built-in validators.  For example, if the user model requires that a username and email is given, all fields have a maximum length, the email field contains a valid format of email address, the password is confirmed in a separate field and the username is unique:</p>
<pre class="indent">class User &lt; ActiveRecord::Base
  validates_presence_of :username
  validates_presence_of :email
		
  validates_length_of :username, :maximum => 12, :allow_nil => true
  validates_length_of :email, :maximum => 80, :allow_nil => true
		
  validates_format_of :email, :with => /^([^@\s]+)@((?:[-_a-z0-9]+\.)+[a-z]{2,})$/i, :allow_nil => true

  validates_confirmation_of :password

  validates_uniqueness_of :username
end</pre>
<p class="indent">Something of interest in the above example is the :allow_nil => true on some of the validation.  We have said that the email address is compulsory, get when validating the format we allow it to be blank.  Surely this is a contradiction?  It&#8217;s not and the reason is to avoid multiple error messages if a compulsory field is left blank.  If the email address is not given, the validates_presence_of will fail validation and trigger an error message.  However, the validates_format_of would also generate an error as blank is not a valid address.  Thus, tell the validation of the format to ignore a blank string.</p>
<p class="indent">Whilst the built in validators in Rails are very useful, any specific validation required which is not covered by them can be added simply by putting the code in a method called validate.  This will be automatically called during validation.  For example, a product with an effective date and an expiry date should validate that the expiry date is not before the effective date.</p>
<pre class="indent">class Product &lt; ActiveRecord::Base
  def validate
    errors.add(:expiry_date, 'Expiry date must not be before effective date') if !expiry_date.nil? &#038;&#038; expiry_date &lt; effective_date
  end
end</pre>
<p class="indent">As we will see later, validation logic is also useful within the view as compulsory fields and error fields can be automatically marked for the convenience of the user simply by consulting the model.</p>
<h4>attributes</h4>
<p class="indent">Anyone used to a Java/Hibernate type environment will be familiar with the excessive repetition required to define a simple class and attributes - within the DDL to build the database table, the ORM mapping file, the Java class and finally the required getter and setter methods.  Put a column in a table and by default Rails will do the rest for nothing.  If the product table contains a column description, then the Product class will implicitly contain a getter method, description and a setter method, description=(description).  This is exceedingly useful and saves loads of development time, but of course, can be expanded upon and overwritten if a particular application demands it.</p>
<p class="indent">For example, suppose the product name should be kept in the database in uppercase only.  This can be achieved by simply overwritting the setter method.</p>
<pre class="indent">class Product &lt; ActiveRecord::Base
  def product=(product)
    self[:product] = product.upcase
  end
end</pre>
<h4>filters</h4>
<p class="indent">Like the validate method, filters can be defined to be called at specific points in processing the model.  For example, if a parameters table always has exactly one row, it will be added during installation and the model must not permit insertion or deletion of rows.</p>
<pre class="indent">class Parameters &lt; ActiveRecord::Base
  before_create   :filter_create
  before_destroy  :filter_delete
		
  def filter_create
    if !Parameter.count.zero?
      raise 'Insertion of multiple parameter records is not permitted.'
    end
  end
		
  def filter_delete
    raise 'Deletion of parameter records is not permitted.'
  end
end</pre>]]></content:encoded>
			<wfw:commentRss>http://romtex.co.uk/2007/11/27/models/feed/</wfw:commentRss>
		</item>
		<item>
		<title>migrations</title>
		<link>http://romtex.co.uk/2007/11/03/migrations/</link>
		<comments>http://romtex.co.uk/2007/11/03/migrations/#comments</comments>
		<pubDate>Sat, 03 Nov 2007 16:52:59 +0000</pubDate>
		<dc:creator>Romtex</dc:creator>
		
		<category><![CDATA[rails]]></category>

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

		<guid isPermaLink="false">http://romtex.co.uk/2007/11/03/migrations/</guid>
		<description><![CDATA[Ruby on Rails migrations allows the complete definition of an Object Relationship Mapping in just one place.  Using a more traditional approach of Java and Hibernate would require DDL to make the database table changes, possibly SQL to populate default values, XML mapping files and finally a Java class complete with getter and setter [...]]]></description>
			<content:encoded><![CDATA[<br/>
<p>Ruby on Rails migrations allows the complete definition of an Object Relationship Mapping in just one place.  Using a more traditional approach of Java and Hibernate would require DDL to make the database table changes, possibly SQL to populate default values, XML mapping files and finally a Java class complete with getter and setter methods.</p>
<p>Rails achieves all of this in just one migration file.  Each migration contains a couple of methods - one to move up to this version of the database model, and one to move down.  Typically these might respectively contain code to create a new table and drop it.</p>
<span id="more-15"></span>
<p>For example, to add a simple users table:</p>
<pre>class CreateUsers &lt; ActiveRecord:Migration
  def self.up
    create_table :users do |t|
      t.column :username,  :string, :limit => 12,
                           :null => false
      t.column :full_name, :string, :limit => 40, 
                           :null => false
    end
  end

  def self.down
    drop_table :users
  end
end</pre>
<p>The migration file does the job of the DDL and SQL allowing both database structure changes and data setup to occur.  Rails&#8217; axiom of convention over configuration removes the need for any mapping file or even the definition of the underlying class.</p>
<p>To show what else is possible in a migration it&#8217;s possible to add a unique constraint:</p>
<pre>def self.up
  ...
  add_index :users, :username, :unique => true
end</pre>
<p>Or add an admin user:</p>
<pre>def self.up
  ...
  User.create :username => 'admin', :full_name => 'Admin'
end</pre>
<p>As the contents of the up method are simply executed in sequence it&#8217;s possible to get around chicken and egg type scenarios.  Suppose for audit purposes our user table holds a couple of fields to indicate which user created a new user and updated an existing user.  Normally these fields would not allow nulls because they can always be populated.  But who created the default admin user?  It makes sense to be admin itself however, how can we defined the creator as a user who doesn&#8217;t exist?  The solution is simple.  Create the table allowing the created by field to allow nulls, add the admin user, set the created by field to this new user then update the table to no longer allow nulls.</p>
<pre>def self.up
  create_table :users do |t|
    ...
    t.column :created_by, :integer
  end

  User.create :username => 'admin', :full_name => 'Admin'

  admin_user = User.find_by_username('admin')
  admin_user.created_by = admin_user
  admin_user.save
	
  change_column :users, :created_by, :integer, 
                                     :null => false</pre>
]]></content:encoded>
			<wfw:commentRss>http://romtex.co.uk/2007/11/03/migrations/feed/</wfw:commentRss>
		</item>
		<item>
		<title>installing ruby on rails</title>
		<link>http://romtex.co.uk/2007/09/24/ruby-on-rails/</link>
		<comments>http://romtex.co.uk/2007/09/24/ruby-on-rails/#comments</comments>
		<pubDate>Mon, 24 Sep 2007 15:23:36 +0000</pubDate>
		<dc:creator>Romtex</dc:creator>
		
		<category><![CDATA[rails]]></category>

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

		<guid isPermaLink="false">http://romtex.co.uk/new-design/2007/09/24/ruby-on-rails/</guid>
		<description><![CDATA[This is the first in a series of articles about developing a web application using Ruby on Rails.  In this article we&#8217;ll look at installing Rails and creating a development environment.
To give a good realistic base for web application development we&#8217;ll install Edge Rails along with a suitable database and add some good options [...]]]></description>
			<content:encoded><![CDATA[<br/>
<p>This is the first in a series of articles about developing a web application using <a href="http://www.rubyonrails.org/">Ruby on Rails</a>.  In this article we&#8217;ll look at installing Rails and creating a development environment.</p>
<p>To give a good realistic base for web application development we&#8217;ll install Edge Rails along with a suitable database and add some good options including Globalize for international support and database sessions.  This example installs Rails in a Windows environment but there&#8217;s not much difference for a Mac or Linux installation.</p>
<span id="more-14"></span>
<h4>ruby</h4>
<p class="indent">Get the latest version of Ruby from the <a href="http://www.ruby-lang.org">Ruby</a> programming site.  A standard Windows installer is available and we&#8217;re currently using version 1.8.6.</p>
<h4>rails</h4>
<p class="indent">After Ruby is installed you can obtain the latest stable release of Rails as a Ruby gem.</p>
<pre class="indent">$ gem install rails --include-dependencies</pre>
<h4>database</h4>
<p class="indent">You should already have your choice of database installed so we won&#8217;t cover that here.  We currently use Rails with either <a href="http://www.mysql.com">MySQL</a> or <a href="http://www.sqlite.org">SQLite</a> and in the past have used other databases too.  The significant point during the Rails installation is to get hold of the appropriate Ruby gem for your database.  For example, if you are using MySQL:</p>
<pre class="indent">$ gem install mysql</pre>
<h4>create your Rails application</h4>
<p class="indent">The remainder of the installation is required to be done within each application so create your Rails application now.</p>
<pre class="indent">$ rails demo
$ cd demo</pre>
<p class="indent">At this time remember to change the database.yml file to reflect your choice of database.  For example:</p>
<pre class="indent">defaults: &#038;defaults
  adapter: mysql
  username: demo
  password: ...
  host: localhost
  encoding: utf8

development:
  database: demo_development
  <<: *defaults

test:
  database: demo_test
  <<: *defaults
</pre>
<h4>edge rails</h4>
<p class="indent">Rails is evolving quickly so we believe it is advisable to be at the edge.  If you don&#8217;t you could find yourself missing new features and using code which will deprecate in a future version.  We prefer to fix the version of Rails within each application so that you always now at deployment that everything will work as expected.  Of course, you can refresh your frozen version of Rails from time to time during development to ensure you are as close to the edge at release as possible.  At the same time, we&#8217;ll generate the rdoc.</p>
<pre class="indent">$ rake rails:freeze:edge
$ rake doc:rails</pre>
<h4>database sessions</h4>
<p class="indent">To store session data in the database&#8230;</p>
<pre class="indent">$ rake db:sessions:create
$ rake db:migrate</pre>
<p class="indent">&#8230;and don&#8217;t forget to uncomment the line in the environment.rb file to set the session store to be :active_record_store.</p>
<h4>globalize</h4>
<p class="indent">As much of what we do is international, we find it easier to build i18n in right at the beginning of each application.  We&#8217;ll talk about <a href="http://www.globalize-rails.org/globalize/">Globalize</a> in future articles but for now it&#8217;s a good idea to get it installed.</p>
<pre class="indent">$ ruby script/plugin install 
     http://svn.globalize-rails.org/svn/globalize/trunk
$ rake globalize:setup</pre>
]]></content:encoded>
			<wfw:commentRss>http://romtex.co.uk/2007/09/24/ruby-on-rails/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
