Sebastien Lachance

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 not work, but no error will be thrown

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>

Completely unrealistic example - A Backbone Blog

Last week, while I was playing and coding on my Backbone blog project (backbone-rails-blog), I started wondering if it was something I could use to replace this blog, since I put so much time on it lately. But at the same time I kept telling myself, is Google going to index the content? The short answer is: NO, not now anyway.

The long answer goes like this: Facebook comments are indexed. So there should be a way to provide this content to GoogleBot. I have done my homework and this document, Making Ajax Applications Crawlable) provides some answers. Basically, we need the hashbang) url format. This is achieved with Backbone when we are not using pushstate.

Hashbang url:

http://sebastienlachance.com#!blog-post

My urls:

http://sebastienlachacne.com/blog-post

And frankly, I will not pursue this path. In my case anyway, it provides no real advantages to have an Ajax-powered blog.

In fact, I could have left Backbone and only use it on the admin backend, but as a learning tool, I didn’t want to revert back (and there is so much great blogging platform now anyway).

Do you have any other web apps ideas (other than a todo list or blog)? In my next iteration (that is, the next app), I will be using Backbone with NodeJs and MongoDB. Sounds fun.