Sunday, March 30, 2008

Idea about restful_authentication plugin

If you're using the restful_authentication plugin with your rails projects, there's a simple idea which might be interesting to you.

Idea as I said pretty simple. Rename the users_controller which the plugin generates to profiles_controller, and sequentially change the routes declaration

# from
map.resources :users
# to
map.resource :profile

The reason is simple as well. With the controller you actually manage the user's profile (the registration process for example), not the users collection in really. For administration purposes you may need more standard CRUD controller for the User unit later. And you will extend the existing controller, then you may run into some ugly constructions in it pretty soon.

But with such a simple renaming you'll keep the things more clear and reusable.

Tuesday, March 25, 2008

Another Work Is Done

With love and proud another piece of work been done and now on the air.

Met http://www.redstarpoker.com! Some pretty basic but loverly done rails work.

And don't blame me on the main menu with images, that's all the communists, they like such stuffs.

Monday, March 24, 2008

Creating element event handlers with RJS

If you're working with rails and ajax you probably familiar with the link_to_function helper. And especially with its ability to apply a block where you can put some RJS code. Sometimes it's pretty handy. Especially if you're not much javascript guru or just don't want to get dirty with it.

So, that's cool. But sometimes you might want to use RJS to write some events handling for say a form element. For example you've got a select box which switches different blocks on/off depends on what you choose and you need to wire the 'onchange' event with some logic. In a such case you can pass the :onchange value of the html_options argument in the 'select' helper method. The problem is that it applies a string, not a block where you can put in your RJS stuffs.

And the problem is solvable. There's another helper method which actually applies a block of rjs code and returns a string of compiled javascript code. It's name update_page. The link_to_function method calls it internally. For example you want to switch some blocks depend on a chosen language. This might look like that.

<%= select nil, nil, Language.to_options, {}, :onchange => update_page{ |page|
Language.all.each do |lang|
page << %{$("block-in-langage-#{lang.id}")[this.value == '#{lang.id}' ? 'show' : 'hide']();}
end
} %>

it's a little bit hacky, I've used this 'page << ' stuff and it's not probably a good rjs example. But I want to show the idea only. Whenever you need a javascript string and wish to write it in RJS, you can use the 'update_page' method and have it on.

Friday, March 21, 2008

How to define the pages-cache directory onfly

Generally, in Rails, when you have a deal with the page-cache feature, you define the cache output directory (if define at all) in the environment.rb, something like that

config.action_controller.page_cache_directory = RAILS_ROOT + "/public/cache/"

But sometimes you may need to add something special to the path on fly, when the controller is working. Say a language prefix or so. And you can do so in a nice one-line patch. You should overload the 'cache_page' method (not the 'caches_page' one), like that

def cache_page(content=nil, path=nil)
super content || response.body, path || (@language_name + request.path)
end

And you won't need to touch anything else, case all your controller caching settings will eventually call the method. Just notice, that the method should be public. And don't forget to add your hacky prefix to your sweepers.

That's pretty much it.

How to setup updated_at field manually

There's a simple case. Say I've got a model which logic depends on the magic updated_at field and I would like to test it. But the question is how to set the value manually up, when you need it? If you try something like

@article.update_attributes :updated_at => 10.minutes.ago

Then you'll have your updated_at field set to Time.now whatever you pass in it, because ActiveRecord will overwrite it by default.

The answer is simple, use the 'record_timestamps=' class-method which switches on/off the automatic updating of the created and updated fields.

Article.record_timestamps = false
@article.update_attributes :updated_at => 10.minutes.ago
Article.record_timestamps = true

That's it.

Monday, March 17, 2008

Single Table Inheritance With Nested Classes in Rails

There's a feature in Rails, which allows you to have several classes on the same table. You define a string column named 'type' and then inherit your new classes from the basic unit class. Pretty simple and sometimes very useful. It's called Single Table Inheritance or simply STI.

But in some cases there are might be quite a number of subclasses and you may even don't know how many of them will be. Say a simple case. You've got a class Game which presents a basic game model data-structure, and then you've got several subclasses which represents real games logic which have just the same data-structure but different behavior. The customer said I want those five games now and probable another good five later.

Ok, that's fine and probably an excellent opportunity for using the STI feature. But the thing which bothers me in the case is the big and unpredictable number of subclasses, and as for me, I would like to not have such a mess in my app/model/ directory.

A possible solution is in having nested subclasses for the Game class. In general it might look like this

class Game < ActiveRecord::Base
#........ some basic crap .........

class Klondike < Game
end

class Poker < Game
end
end

Then, when you create instances of the subclasses you'll have the 'type' attribute set properly to the name of the subclass.

>> g = Game::Poker.new
>> g
=> #<Game::Poker type: "Poker", ....>

This will work just the same way if would define a usual class like class PokerGame < Game, but this solution with nested classes allows you to organize your subclasses better. Now you can, by following the rails naming convention, create the following directories/files structure

app/
models/
game/
klondike.rb
poker.rb
game.rb

and then inside, say, the poker.rb file define your nested classes like that

class Game::Poker < Game
....
end

In such a way you'll keep your subclasses organized well and still will be able to use the STI feature.

Thursday, March 13, 2008

Story Writing Is Fun

This is about the Story Framework, which is a part of the RSpec library. There's no documentation for the stuff on the official site and very few articles over the Internet, so I think one more example won't hurt, at last it's a really awesome tool.

Generally, Story Writing is a part of BDD, which allows you to define the scope of a system feature along with the criteria of the feature acceptance. If simple and basically, then Stories for BDD are about the same as integration tests for TDD. In case of Rails, this will be RSpec's replacement for the rails native integration tests. The general difference is that it based on the RSpec's expectations. Terrific and fun replacement I should say. 8)

So, lets get down to the deal. My goal for now is to display how a general story should look like and what can you do with it. And because I'm not going to display the stories based development process in action, I'll break the very first rule, precisely "test first". But don't get fooled, in general story writing is a part of BDD process, and in a correct sequence you are writing story first, then you write your specs and code. I just want to show an average story by itself.

Ok, lets assume we have got a rails project, with the rspec and rspec_on_rails plugins installed. Then assume you've generated an Article model rspec_scaffold, then you have installed the restful_authentication plugin and generated the whole user's stuffs. Those are pretty much standard actions, so I won't stop on them here.

First of all you should check your specs and get sure that all of them are happy. Here you should understand the difference between the sepcs and stories. Your specs describes the system objects behavior, this is an equivalent of unit-tests. Stories describes how a whole system (or its aspect) behaves in certain situations. So, writing stories don't forget about your specs, that's your backup and this is not a bad idea to keep the autotest util runned on somewhere in background.

Each story for a first sight might look like something free but they have a particular format. Each story contains one or more scenarios and each scenario describes a particular situation in a simple form setting -> action -> result. Something like that

Story "name", "description" do
Scenario "short descritpion" do
Given "something"
And "something else"
And "maybe something more"

When "I do something"

Then "the system will produce that"
And "it should do that also"
And "probably this one should get happened too"
end

Scenario "..."
end

This is a pretty basic example, just to show common Story structure. As you see this is a piece of ruby code, you calls something, put in it variables and blocks. You even my execute the code if you write it in a file. But now you should notice the three blocks

  • Given [And, And...] - describes the action setting
  • When - describes the action
  • Then [And, And...] - describes the action results

Each of the blocks in really applies additional variables and blocks, the string you passing in is a name of the step. As the story doesn't have any implementation in it, if you have it executed, all the blocks will be marked as "pending".

Ok, this is pretty much it. Lets now write something more meaningful. Say we want that all registered and anonymous users could see the articles index. So we are writing a story.

Story "articles browsing", %{
As a registered or anonymous user
I want to have an access to the articles browsing
So all the people around the world could see the articles
}, :type => RailsStory do

Scenario "anonymous user gets the index" do
Given "an article" do
@article = Article.new
@article.stub!(:valid?).and_return(true)
@article.save
end

When "I get to the page", articles_path do |path|
get path
end

Then "I see the index" do
response.should render_template('index')
end
end

Scenario "registered user gets the index" do
Given "logged in user" do
@user = User.new :login => 'asdf', :password => 'asdf'
@user.stub!(:valid?).and_return(true)
@user.save

post sessions_path :login => @user.login, :password => @user.password
end

And "an article"

When "I get to the page", articles_path

Then "I see the index"
end
end

As you see we are using the RSpec expectations syntactics and doing some activities inside the blocks. You may add more And "..." do; end blocks into your Then description and describe more result criteria you would need to check out. And you can use just the same RSpec tools as inside your controller specs.

More interesting the second scenario, especially this part

And "an article"

When "I get to the page", articles_path

Then "I see the index"

If you have executed the story, you won't see any pending elements, everything will be executed. And there's the tricky point. Each step you fill up with code will be saved inside a story as a method and might later be called by the name you have specified. And sure you can specify arguments for a step. See the case with the When step. In the second call instead of the articles_path could be any path and it would be used inside the block specified in the first scenario but executed in the scope of the second scenario.

Okay, that's nice. But if then we want to write another story, for the "show" action. You don't need to be a master-mind to figure out that this will be a pretty much similar one. Wanna your DRY for the case? No problem, you can extract the steps out of stories at all and create a steps collection. Like that.

class ArticlesAccessSteps < < Spec::Story::StepGroup
steps do |define|
define.given "an article" do
@article = Article.new
@article.stub!(:valid?).and_return(true)
@article.save
end

define.given "logged in user" do
@user = User.new :login => 'asdf', :password => 'asdf'
@user.stub!(:valid?).and_return(true)
@user.save

post sessions_path :login => @user.login, :password => @user.password
end

define.when "I GET the page" do |path|
get path
end

define.then "I see the $page_name" do |page_name|
response.should render_template(page_name)
end
end
end

You might put the code inside the stories/helper.rb file or inside a separated file and require it, or just put above your story and then write your stories like that:

Story "articles browsing", %{
As a registered or anonymous user
I want to have an access to the articles browsing
So all the people around the world could see the articles
}, :type => RailsStory, :steps => ArticlesAccessSteps.new do # <- watch out the ':steps =>' attribute
Scenario "anonymous user gets the index" do
Given "an article"
When "I GET the page", articles_path
Then "I see the index"
end

Scenario "registered user gets the index" do
Given "logged in 'user'"
And "an article"
When "I GET the page", articles_path
Then "I see the index"
end
end

Story "article displaying", :type => RailsStory, :steps => ArticlesAccessSteps.new do
Scenario "anonymous user gets the index" do
Given "an article"
When "I GET the page", article_path(@article)
Then "I see the show"
end

Scenario "registered user gets the index" do
Given "logged in user"
And "an article"
When "I GET the page", article_path(@article)
Then "I see the show"
end
end

Surely it looks much more readable and still will be executed and do what you need. And there's another trick I haven't mentioned. This piece of code

define.then "I see the $page_name" do |page_name|
response.should render_template(page_name)
end

Inside the steps definition. This magic construction "$page_name" will parse out the template name right out of the passed step name and put it into the block. Therefore you can write your steps like

Then "I see the index"
.............................
Then "I see the show"

The same step will be involved, but first time with the 'index' page_name, and the second with the 'show' page_name.

This way you can define your own small macro-language to describe your system behavior with short and easy to understand phrases. You even might show the stuff to your customer and he will understand what's going on and will be sure that the system is doing what he need.

And this is not the end again. As you probably noticed, that after you have moved all the steps code into a standalone class, your story contains nothing but text. In such case you can even go further and put your stories in a plain text. In a such format

Story: articles browsing
As a registered or anonymous user
I want to have an access to the articles browsing
So all the people around the world could see the articles

Scenario: anonymous user gets the index
Given an article
When I GET the page /articles
Then I see the index

Scenario: registered user gets the index
Given logged in user
And an article
When I GET the page /articles
Then I see the index

Isn't that great? You can save that text in a file and then execute it with a simple runner, similar to this one.

require 'rspec'
require 'your_gears' # <- require your necessary files

runner = Spec::Story::Runner::PlainTextStoryRunner.new('your/plain/text/story/file/name')
runner.steps << ArticlesAccessSteps.new
runner.run

You may have one script for all of your textual stories it's up to you. And you'll need to change a little your When step to be like When "I GET the page $path" so it was catching up your urls you specify in the story.

That's it. If you ever written integration tests with the native rails integration tests framework, you probably noticed how ugly and complex they tend to become when the application logic gets serious. So the Story Framework of RSpec offers you an excellent opportunity to change the things for better. With stories you can easily organize your system behavior description in collections of simple scenarios and inside each scenario you can easily set up the necessary conditions, run necessary actions and check the result. And that more important you can do in a very simple way, just with few short strings which anyone can understand.

That's what I wanted to show today.
So long and write the stories it's fun! ;)

Wednesday, March 12, 2008

RSpec Dummyfication

When you're working with rspec and describing models relations you probably will need some dummy models, which wont bother you with all those validation stuffs. Yes, there's mock_model method, but the problem with it is that it stubs all the model methods first and the mocks don't have any relationships with the database.

And then if you need for your integration tests real models which will respond as real models and have database identification, you probably might find useful the following trick. Add the following strings into your spec_helper.rb file.

module Dummyficator
def dummy_inst(klass, attrs={ })
inst = klass.new attrs
inst.stub!(:valid?).and_return(true)
inst.save
inst
end
end

include Dummyficator

After this you'll be able to create dummy model instances in your specs like that

describe Group, "with users" do
before do
@group = dummy_inst Group
@group << dummy_inst User
@group << dummy_inst User, :username => 'dummy'
end

it "should have two users" do
@group.should have(2).users
end

it "should not destroy users" do
@group.destroy
User.find_by_username('dummy').should_not be_nil
end
end

This way you will be able to create new and new database records which will behave just as they should except the validation, so you can concentrate on the models relations not worrying about the models validation.

Monday, March 10, 2008

The arguments.callee trick

Inside a JavaScript function, you have an access to the local variable arguments, which simulates the list of all the arguments passed to the function. It's quite useful when you have got a function which might be called with different number of arguments.

But this variable is not a list in really, I mean it's not an instance of Array class and it does have additional attributes. For example .callee and dispite it has been marked as depricated feature since JavaScript version 1.5 then it's still working and interesting stuff.

This attribute arguments.callee refers to the current function by itself. It might look pointless, but in really it's quite handy. Say for example with lambda functions, like I showed once that tricks with (function(){...})(); constructions. Such functions don't have any variables which points on them, so if you need to have some lovely recursion in there, you will need this .callee stuff.

Here you go, another brain-kicker with my faworite camelization task.

alert((function(str) {
var _pos = str.lastIndexOf('_'), suffix = str.substr(_pos+1);
return _pos < 1 ? str : arguments.callee.apply(null, [str.substr(0, _pos)])
+ suffix.charAt(0).toUpperCase() + suffix.substr(1);
})('asdf_asdf_asdf'));

See? Generally you can do it only with a prototype method or with a named function. But if you feel particularly evil and wish it have with a lambda function, you can do it like that with arguments.calle.

This is pretty much it.

Sunday, March 2, 2008

TestCase 2.0-alpha is out

As I mentioned the TestCase project is going to be framework independent and now it is.

I've just released the version 2.0-alpha of the project. Functionally it's the same TestCase v 1.0, but the project had some major internal changes so now it runs on its own.

The project is designed such a way that it won't affect any framework stuffs, so you can safely use it with any of your projects. Use it with the lovely mootools or with jQuery if you wish so.

That's it, have fun.