Future on Rails

Using Rails

Nested Forms & Webrat

leave a comment »

I love the new features of Rails 2.3 – one beeing the support for nested forms (forms which let you edit multiple models and associations). However, I ran into some problems with this new approach: 1) Making complex forms with AJAX work with the Rails 2.3 approach and 2) Testing those forms with Cucumber and Webrat.

1) Making complex forms with AJAX work with the Rails 2.3 approach

When I tried to use the approach from Ryan Bate’s railscast “Complex Forms Part 3”, ran into several issues with organizing my partials and getting the HTML and Javascript right. Fortunately, Ryan addressed this issue himself => see his github project.

2) Testing those forms with Cucumber and Webrat

Another problem I ran into was testing a complex AJAX form with the new nested forms. Imagine the default app for managing projects, where each project has multiple tasks. To add tasks to a project, I can simply click “Add Task” on the project’s edit page and add form fields dynamically via AJAX. However, how would you address those fields in a cucumber step using webrat?

Given I am on the project edit page
When I click “Add Task”
And I fill in ??? with “my new task”
And I click “Save”
Then I should see …

What to insert for the “???” ? Those fields all have the same label (“Task:”) and the name/id is very cryptic, containing a randomly generated id. I couldn’t find an elegant solution for this issue yet. Please tell me if you know of any solution!

Advertisements

Written by Matthias Orgler

September 30, 2009 at 1:21 pm

Posted in Uncategorized

Tagged with , , , , , ,

The Widespread Abuse of Fixtures

leave a comment »

I thought, everyone on this planet already knew about the purpose of fixtures in Rails…unfortunately I see ¬†the abuse of fixtures in many projects out there.

Fixtures are used by developers for many purposes: unit testing, integration testing or populating the DB with default data. But from all these usage scenarios, fixtures are really only good for integration testing! Don’t use fixtures for unit testing! Don’t use fixtures for populating the DB with default data!

Why not to use fixtures for unit testing?

Fixtures for unit testing is a bad idea. The main reason is that your unit tests become hard to read, because you need two code artefacts to understand them. You also introduce a dependency between test and fixtures (and between this test and other tests using the same fixture data!). It is recommended by most developers, to build unit test objects directly in the test class. This makes every test precondition explicit in the code. It is also easy, because you usually only need an object of one class (without associations).

Why not use fixtures for populating the DB?

It is also very common, to use fixtures for loading default or sample data into the database. But since fixtures are also used for (automated) testing, you might want to separate those two concerns. My recommendation is to use fixtures exclusively for automated integration testing and to use a rake task to populate the DB with default data or test data for manual testing. By using gems like Populator and Faker, you can also quickly create sensible, randomized test data, so that your human testers can do their job. See the great Railscast on “Populating a Database”.

Written by Matthias Orgler

May 11, 2009 at 1:03 pm

Posted in Uncategorized

SVN

leave a comment »

Subversion is a fantastic versioning system (although there’s all the hype about git (to which I am actually switching now)). In the past I stumbled across two problems I want to share with you (including a solution ūüėČ ):

The first thing is that my IDE (Eclipse/Aptana) doesn’t support the latest SVN version. I use Subclipse in the latest version, but I sometimes receive errors that can only be overcome by deleting the whole project and checking it out again. Furthermore Subclipse is not compatible with the latest console version of SVN. Why do I use the console version? Because it is easier to include versioning tasks in Ant or Capistrano or to simply type stuff in the console (as it is common when developing RoR). So finally I disconnected all my projects in Aptana and went ahead to only using the console version of SVN. My experience: the console version is as easy to use as Subclipse, once you’ve learnt a few commands. For everyone wanting to work fast and seeking to avoid trouble, I would recommend to use SVN directly via console.

Another problem I had was to remove directories from SVN via the command line tool. Simply deleting the directory and then trying to check in didn’t work, because SVN was missing the .svn data for that directory. I had to google a little bit to find the simple solution: “svn rm <dir>” will remove a directory from SVN, even if it’s already deleted locally.

Hope this helps some of you to avoid some of the trouble I had ūüėČ

P.S.: Oh, a bonus solution I had to google for in the beginning: If you want to add several new files to your existing repository (e.g. those created by a generator), a simple “svn add .” won’t work. What you want to do is use “svn add . –force” to avoid the warnings SVN gives you for all the already existing files :).

Written by Matthias Orgler

May 5, 2009 at 3:34 pm

Posted in scm

Tagged with , ,

Named Scope or Virtual Attribute?

leave a comment »

The nice thing with Ruby is that it adheres to a basic OO principle: attributes and methods of a class should not be distinguishable. This way the client of class doesn’t have to know, whether “User.full_name” is an attribute or a method. In Rails this could also be a database column, an association or a named scope (all methods dynamically created by Rails). It is very convenient, that all those magic methods and attributes look and act the same :). However, I recently stumbled across a pitfall with named scopes and virtual attributes:

In my application, every “User” can have several “Bands”, of which he is the owner. Furthermore he can belong to several “Bands” as a member:

class User
  has_many :band_members,     :foreign_key => 'member_id'
  has_many :bands_as_member,  :through => :band_members, :source => 'band'
  has_many :bands_as_owner,   :class_name => 'Band', :foreign_key => 'owner_id'
  has_many :bands_as_member, :through => :band_members
end
class Band
  has_many    :band_members
  has_many    :members, :through => :band_members
  belongs_to  :owner, :class_name => 'User'
end

I used the rather long association names in the User model on purpose. If I would have called one of them simply “band”, I could really only receive part of the user’s bands through this one association. What I need to get ALL bands of a user (i.e. those which he owns and of which he is a member), I will either have to define a named scope or a vritual attribute combining all bands. Initially I thought it wouldn’t make a difference, since both approaches result in something called “User.bands” which returns all bands of the user.

Imagine, we would have modelled this as a virtual attribute (as I did, because I found it easier to think up than a SQL query ūüėČ ):

class User

  def bands

    self.bands_as_owner + self.bands_as_member

  end

end

This thing returns an array of all bands. What’s wrong with this approach? Well, this virtual attribute doesn’t act exactly like a named scope or an association. If you try the followin in a typical Band controller, you get an error:

def destroy
  @band = current_user.bands.find(params[:id])
  @band.destroy
end

The error you get doesn’t really give a hint to what happens here. After reading some documentation about the internals of Rails, I came across the problem. The thing is: our virtual attribute returns a simple Ruby Array – which doesn’t come with the find method of Rails. In contrast, when Rails dynamically creates such a method for an association or a named scope, the returned object is a proxy only ACTING AS IF it was an Array. In addition it also enhances the object by Rails’ magical methods you know.

This difference between virtual attributes and named scopes in the case mentioned above can really bite you. So be aware of the subtle differences between both approaches.

Written by Matthias Orgler

April 30, 2009 at 2:19 pm

Posted in Uncategorized

Organizing Views for Resources

leave a comment »

When developing a Rails application, most of the objects we deal with are “resources” (well, that’s if we think RESTful, of course ;)). I noticed I use a common theme to organize the view part of those resources.

The straight forward way would be to have a view for most every REST action: index, new, edit and show. What I noticed is, that new and edit are very similar: both present a form to edit the resource. So the first thing I usually do is to create a partial called _form.html.erb to refactor the common parts of new and edit into. You could even go further: in many modern applications, the user should be able to perform “in place editing” of resources. This means that the show view basically represents show, edit and new all in one. Depending on the case at hand you could either eliminate all those views and simply use “show” for all actions or you could keep them and extract the common code into a partial (like the _form.html.erb mentioned above).

Another commonality among resources is that they’re views of a single resource or a list of resources. The single resource is usually presented in the new, edit and show views, the list is usually presented in the index view. But in a real world application you might want to display resources or lists of resources in different places on your site. You might e.g. have a kind of dashboard where the user has an overview over some of her resources. To facilitate this code reuse, I usually create two view partials for each resource: a _widget.html.erb displaying a single resource, and a _list.html.erb displaying a list of all resources (maybe filtered/limited by some (search) criteria). These two partials can then be used in every place where those resources need to be displayed. In very simple cases, the _list.html.erb might not be necessary, because you could use the widget partial with a collection.¬†

I hope, my organization of resource views gives you useful ideas how to design your code. I’m always eager to learn and would appreciate any thoughts on this topic!

Written by Matthias Orgler

April 29, 2009 at 1:17 pm

Posted in code design, refactoring

Tagged with

AOP on Rails

leave a comment »

AOP can make a software design very DRY and tidy. This post discusses a method to do aspect-oriented programming in RoR.

From my resarch at university as well as from real world projects I know what a fantastic tool aspect-oriented programming is. Yes, it’s a sharp knife, but if you handle it correctly, you can do great things without damaging your design ;). The downside is: Ruby is not an aspect-oriented language.¬†Having said this, the Ruby language comes with some great constructs to allow an emulation of AOP.

First: Why the hell do we need AOP?? Let me give you a real world case that led me to an aspect-oriented design. The example comes from a social web app I was building for a client, so everyone should be able to relate to it.

Typical parts of a social web application are “Users”, “Friendships” or “Chats”. Basically a user can be friend with any other user in the network (m:n relationship). The same goes for chats: a user can chat with any other user. How would you model this in Rails? Well, the first thought might lead to something similar to Hartl/Prochazka’s solution in RailsSpace (pseudeo code):¬†

class User
  has_many :friendships
  has_many :friends, :through => :friendships
  def become_friend_with(other_user)
    self.friendships << Friendship.create(:inviter => self, :invitee => other_user)
  end 
  def friend_of?(other_user)
    Friendship.between?(self, other_user)
  end 
 end

This is a good approach. However, watch what happens, if we add “Chats” or other features to the “User” class:

class User
  has_many :friendships
  has_many :friends, :through => :friendships
  has_many :chats
  has_many :messages
  has_many :channels
  ...
  def become_friend_with(other_user)
  def subscribe_to_channel(channel_name)
  def active_chats 
  ...

end 
My point is: the “User” class shows the blob anti-pattern. Diverse features amass in the “User” class and make it more and more incoherent. The consequence is a class spanning several screens in code and various features that you need to find “somewhere” in that class (as opposed to finding a feature in a class with its name). Part of the problem with incoherence is already solved by using specialized classes for “Friendship”, “Message” and so on – the “User” class only acts as a facade and delegates method calls to the specialized classes. However, from a design point of view I would love to eliminate most of this delegation code from the “User” class, since it doesn’t really belong there and only clutters up the code. Furthermore I would like to be able to eliminate or add features with a simple line of code: one of my clients might need “Chats”, the other might not want them. It would be great, if I could simply delete a line with “feature Chat” from the “User” class an be done with a new version :). The notion of “features” comes from feature-oriented programming (FOP) and software product lines (SPL). Basically all these features are different aspects of a User class: the aspect of being a friend, the aspect of being a chat partner, … . This is why it’s called aspect-oriented programming. The goal is now, to put each aspect in its own code entity (class or module).

How to do this in RoR? Let me first show you what happens, once you go the AOP way. The User class become pretty sleak and looks like this:

class User
  include FriendshipUser, ChatUser, ChannelUser, ...
end

If I didn’t wanted a “User” to participate in “Friendships”, I can now simply remove the “FriendshipUser” from the include line and be done. If I wanted to add VoIP capabilities to the “User”, I could simply add the “VideoChatUser” module to the include statement. Did we save any code this way? No! But now all code belonging to the aspect of “Friendship” resides in its own module (called “FriendshipUser”):

module FriendshipUser
  def friend_of?(other_user)
    Friendship.between?(self, other_user)
  end
  ...
end 

This makes the classes/modules more coherent, maintainable and understandable. The “FriendshipUser” module is now an aspect and enhances the “User” class with functionality by adding methods. I would personally put this module definition in the same file as the “Friendship” class. What’s still missing are the declarations of the has_many-relationships and maybe validations, named scopes and so on. This requires a little meta programming, but it is still fairly simple:

module FriendshipUser
  def self.included(includer) 
    includer.class_eval do 
      has_many :friendships
      has_many :friends, :through => :friendships
    end 
  ...
  end
end 

An important feature of AOP is the possibility to enhance methods of the “User” class with new features – without the “User” class having to know about it. In plain old OOP, the only possibility to enhance functionality of a class later on is inheritance and overriding methodes (UserAsFriend < User). If we wanted to be able to have the new functionality in the base class already (“User” in this ¬†case), we could fall back to the template method pattern. However, all of this would mean to plan in advance for all possible future features – this doesn’t sound very agile to me. The aspect-oriented solution is the notion of “join points” and “pointcuts”. A “join point” is basically any defined point in the static or dynamic structure of an application: methode calls, method executions, instantiations, … . “Pointcuts” are like search queries, that filter out specific join points of interest to the aspect. Let’s say, when a new “User” is created, we want it to automatically become friend with one of our support guys. Of course you already know, how this would be possible in Rails:¬†

module FriendshipUser
  def after_create
    self.become_friend_with(support_guy)
  end
end

We can use the lifecylce methods of Rails to hook into existing methods. Unfortunately this is a bit limited compared to freely definable pointcuts in an aspect-oriented language – but it works in many cases in Rails. before_filter and after_filter would be nice tools here, but they’re only made for controllers. Observers use a variation of the template method pattern and thus also won’t qualify for a pointcut solution. One hope I have are a few attempts of producing an AOP extension for the Ruby language – I will keep an eye on those (I know about¬†Aquarium).

If you have any questions, thoughts or suggestions on this topic, please leave me a comment or send me a message. I’m eager to help, discuss and learn :).

Written by Matthias Orgler

April 28, 2009 at 1:20 pm

Posted in development techniques

Tagged with , , , , ,