Sebastien Lachance

Rails model without ActiveRecord

Common scenario for a contact form.

Here is how I do it:

Model without ActiveRecord in Rails
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Contact
  include ActiveModel::Validations
  include ActiveModel::Conversion

  def initialize(attributes = {})
    attributes.each do |name, value|
      send("#{name}=", value)
    end
  end

  def persisted?
    false
  end

end

A real world application with Backbone and Rails - My story … so far

This is a post about the technology stack I use for my new project (available in the next few weeks).

I can’t tell you right now what it is… (I’m a little paranoid that my idea will be stolen :) ). But really soon I promise.

tl;dr

I used Rails, PostgreSql, Backbone and Twitter Bootstrap.

This is how I decided of the technology stack.

Web framework

Most of my real-world experience was with Rails and .NET. I have done a lot of work in ASP.NET, MVC, Winforms, services, etc. Since I have a lot more experience in the Microsoft world, it would have been logical to use ASP.NET MVC, but Rails is part of my life for the last 2-3 years and it’s a lot more fun and the development process is reduced by a strong percentage. Don’t believe me? Try it yourself, you’ll see what I mean. I have nothing against Visual Studio, It’s a fantastic IDE and it’s becoming pretty fast. But, not fast enough. Waiting for Visual Studio to build and attach the debugger is too painful when you are in a hurry. NuGet is starting to be really great but …

So I will use Rails latests version (3.2.3 at the moment) with Vim, all on my Macbook Pro. RVM included. I strongly belived that when you launch a startup you want to launch something as fast as possible and adjust to the need of your users. I can’t built every tools from scratch. So I will use existing tools instead of reinventing the wheel. Rails assets pipeline will help compress and manage assets easily, Sass and CoffeeScript support out of the box. You need something complicated that you don’t have time for? Gems! There is Gems for almost everything.

I had considered and was almost sure that I would use Node. But I have realized that I couldn’t be proefficient soon enough.

Database

For the database, I made the mistake to use MySql on my last project when I needed fulltext search. I will not use PostgreSQL. With Rails however, I didn’t see any changes in my development process. Require the pg gem instead of MySql and it’s done. NoSql is tempting but I don’t see any real advantages for me, for now.

Client-side styling

For the css grid framework I wanted to use Skeleton but decided at the last moment to use Twitter Bootstrap (I know…). You need to know that I am not a designer and Twitter Bootstrap has some customization possible. And it has all this Javascript plugins that are just great Twitter Bootstrap

Backbone

An obvious choice was to use Backbone. I didn’t knew why at the time, but I am glad I didn’t threw this choice away. It was important for me to be a client-side application. As I previously read, Performance is a feature. And it is one of my key principle.

Backbone has a big learning curve. Here is how I manage to use it effectively:

I wanted to use TDD to develop the client-side, but gave away after the first week. It was getting in my way and for me I didn’t feel I was learning Backbone, I was learning how to test javascript. What I did instead was to only use the model part of Backbone and implement the rest using JQuery. It worked really well, until I finally saw a pattern emerging were I needed to reuse a certain part of the interface. So I created a view, listening to the change event of the model. After a while, I added another event listener to the blur event of an text input, and then listening to the reset event of a collection. And then another and another. I saw another case where a view could be appropriate and started implementing it. Created a sub view. Realized that a Router would be a welcome addition. And now I see where I could use it everywhere.

I can now say that no more of the original JQuery code is left and everything is in either a view, model, router or collection.

Authentication

One of the other big challenge I faced was with authentication. It was a requirement to use a flexible authentication scheme.

Twitter and Facebook were my two absolute must as well as the normal user/password combination. Thankfully, the Rails ecosystem has some great gems and OmniAuth was exactly what I was looking for.

A final note

I strongly believe in this project, not to generate a lot of revenue, but to help those in the same situation as WE were with our first baby… (ohoh a hint here).

Rails Assets Pipeline and missing assets

I moved the entire Guide des Commerces from Rails 3.0.10 to Rails 3.2.3. I have to admit it, I was afraid of the assets pipeline and my first deployment attempt resulted in a lost afternoon and a bad case of stress. I had to revert back and lose some customer data (just my associate data).

The problem was that I tried to use the assets pipeline for half the application and let everything in the public folder for the second half (admin part). I’m pretty sure it is possible.

Now everything is moved and I am actually quite happy. One css and one js per page is finally a dream came true.

Anyway, what I really wanted to talk here is about one of the problems I had. When calling the assets precompile rake task, one compiled css file was missing. Like one of the manifest wasn’t read or executed.

When you have multiple manifest files (not called application.css or application.js), you actually have to tell which additionnal one to precompile.

config/application.rb
1
config.assets.precompile += ['administration.js', 'administration.css' ]

One gotcha with scss manifest:

If you are using scss files as manifests, you need to use the compiled version.

Like this:

config/application.rb
1
config.assets.precompile += ['application.css' ] # this will work for application.css.scss 

Instead of:

config/application.rb
1
 config.assets.precompile += ['application.css.scss' ]  # this will not work, but no error will be thrown

Method decorators in Ruby

While I was following the #railsconf thread on Twitter, I heard some talking about method decorators with Ruby. I’ve always wondered if there was a way to emulate the Attribute we have in .NET.

Turns out it is possible (and with added value!). Using the method_decorators gem allow precisely that functionnality with some extras.

Defining a decorator

Defining a decorator
1
2
3
4
5
class ADecorator < MethodDecorator
  def call(orig, *args, &blk)
    orig.call(*args, &blk)
  end
end

This decorator actually does nothing, since we call the original method with supplied arguments and block (if provided).

Using the decorator

Using the decorator
1
2
3
4
5
6
7
8
class AClass
  extends MethodDecorators

  +ADecorator
  def do_something()
  end

end

We can now do something before and after the call to do_something and even modify the return value.

A practical example

I’ve had this little problem in .NET where I wanted to profile different method calls to see how much time they took to execute and send back the result via MiniProfiler. For this, I wanted only to add an attribute to those methods. The only way I have found that possible without the use of an advanced profiling tool was to use PostSharp and it’s injecting code feature. The Attribute functionnality does not offer any kind of before and after hook on execution.

A custom implementation would look like this.

MiniProfiler Attribute with PostSharp and C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[Serializable]
public class ProfilingAspectAttribute : OnMethodBoundaryAspect
{
  private IDisposable _profiler;

  public ProfilingAspectAttribute
  end

  public override OnEntry(MethodExecutionArgs args) {
    _profiler = MiniProfiler.Current.Step(string.Format("{0}.{1}",
       args.Method.DeclaringType.Name, args.Method.Name);
  }

  public override OnExit(MethodExecutionArgs args) {
    if (_profiler != null) {
      _profiler.Dispose();
      _profiler = null;
    }
  }
}

PostSharp will inject the OnEntry and OnExit code at the start and at the end of the “decorated” method. By default, there is no way to achieve that easily.

With Ruby, the method_decorators gem and a custom profiler, it would look like this.

A custom profiling decorator
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Profiling < MethodDecorator

  def call(orig, *args, &blk)
    profiler.start
    orig.call(*args, &blk)
    profiler.stop
  end

end

class SomeClass

  +Profiling
  def some_method_to_be_profiled
    #some complex calculations
  end

end

How nice is that?

Learning Rails : assert_valid_keys

While reading the source code of FactoryGirl, I came accross this method and tried to find where in FactoryGirl it was defined. Turns out it’s in Rails since version 3.0 (more specifically in active_support/core_ext/hash/keys).

It’s an instance method of the Hash class, and what it allows you to do is to throw an ArgumentError when an unknown key is found on the hash instance.

valid keys
1
2
{ :name => "joe", :phone => '555-5555' }.assert_valid_keys(:name, :phone)
 => {:name=>"joe",:phone=>'555-5555'}  # no ArgumentError
missing key in hash
1
2
{ :name => "joe" }.assert_valid_keys(:name, :phone)
 => {:name=>"joe"}  # no ArgumentError
unknown key in hash
1
2
{ :name => "joe", :phone => '555-5555' }.assert_valid_keys(:name)
ArgumentError: Unknown key: phone

assert_valid_keys

Ruby and nested classes

What does it looks like?

class Book
    class Page
    end
end

What is the purpose of nested classes?

It is useful when we want to group classes together instead of trying to keep them distinct. It make no sense in this example to have a standalone Page class without the Book class.

How can we instantiate Page class?

If we try to instantiate it normally:

page = Page.new // will throw Uninitialized constant error

We get: Uninitialized constant Object::Page

Instead we need to use:

page = Book::Page.new

But why using :: ?

Using :: is a way to access constant. Does it make sense? Yes, because nested classes are stored in constant from within the class.

class A
    B = "A constant"
end

A::B will return “A constant”

What can we do with Enumerable#Inject?

Combine all elements of an enumerable with the supplied block (or symbol)

[1, 3, 5, 10].inject { |sum, el| sum + el }

What is happenning behid the scene is this:

1 + 3  # 1. 
4 + 5  # 2. The value of the precedent operation is passed back into the block as the first argument.
9 + 10 # 3. And so on.

#The result will be 19.

You can also pass an ininial value like this:

[1,2,3].inject(10) { |sum, el| sum + el }

10 + 1
11 + 2
13 + 3
The result will be 16.
You can see it as (((10 + 1) + 2) + 3).

The initial value will serve as the first argument of the block.

Iterate over each line of a string in C#

For future reference.

Easy way to go through each line of a string.

string iteration
1
2
3
4
5
6
7
8
using (StringReader reader = new StringReader(txt))
{
    string line;
    while ((line = reader.ReadLine()) != null)
    {
        Console.Log("do anything with the line);
    }
}

ASP.NET MVC ActionLink with image

It’s not as hard as it seems. This is a way to create a link with an image.

link to action with an image
1
2
3
<a href="@Url.Action("Create", "LogBooks")">
  <img src="@Url.Content("~/Content/Images/create.png")" />
</a>