Sass why is useful

Posted by Pablo Ifran on November 26, 2010

Sass is used for generating css files based on his own syntax, it’s very useful because allows you to avoid repeating code across the different scss files using import (allows you to import code from other scss file), or mixins(scss functions). Also, allows you to write varibles, for using in different scss, this makes easier to do different templates based on colors or images for example.

_sprites.scss

@mixin sprite_for($image_class, $x, $y, $image: "/images/sprite_image.png") {
  .sprite_image.#{$image_class} {
    background: transparent url($image) no-repeat scroll $x $y;
    height:16px;
    width:16px;
  }
}
_images.scss
$my_sprite_image_path: "/images/my_sprite_image_path.png";

default.scss

@import "sprites", "images";

@include sprite_for("my_image", 0, 0, $my_sprite_image_path);

That generates

default.css

  .sprite_image.my_image {
    background: transparent url(/images/my_sprite_image_path.png) no-repeat scroll 0 0;
    height:16px;
    width:16px;
  }

So, this is best sorted using this method, because you have the image path in a single file and you use it in other files only by importing the file with the images path, it’s also simpler to remove an image because you only need to find the references to that variable and delete them.

The sass framework also allows you to use the DRY principle because you can write nested selector, I’ll show you with an example:

default.scss

.some_class {
  width: 100px;
  .some_other_class {
    display: block;
  }
}

default.css

.some_class {width:100px;}
.some_class .some_other_class {display:block;}

Doesn’t affect the performance because it generates a css file at development time.

It also allows you to benefit from some of the advantages of css 3 right now.

Best place to live and work. If you are planning to move out … 1

Posted by Gabriela Isnardi on November 23, 2010

According to the Legatum Prosperity Index, Uruguay ranks first in Latin America. This index produces rankings based on the foundations of prosperity, which means that Moove-it is located in a country with factors that will produce economic growth and happy citizens over the long run.

If you have a look at the ranking in the Americas, Canada is on top of the list and Uruguay is in the third place, just after the United States.

For more information please visit:

http://www.prosperity.com/country.aspx?id=UY

You can donwload the pdf file with this information too.

Juggernaut: Chat on Rails

Posted by ivan.etchart on November 19, 2010

To implement chat on Rails we need the Juggernaut gem. The newest version of Juggernaut is build upon nodeJS.
1. Install Juggernaut:
First, install nodejs (http://nodejs.org), redis (http:/code.google.com/p/redis/) and Juggernaut gem (gem install juggernaut).
Then download server git clone …
2. Integrate with Rails to implement chat!
After Juggernaut gem is installed, add it to environment.rb:
config.gem "juggernaut"
Suppose you have a system with user authentication, the idea is to generate an environment where you’re able to chat with other users and see to what extent features can be added in order to create an awesome chat!
Note: Providing a step by step guide to create a working chat isn’t the idea of this tutorial. It’s to show different possibilites to develop on
Juggernaut.

Connecting to Juggernaut from Rails

It’s necessary to add the file WebSocketMain.swf to the public folder. This hasn’t to be exactly this way, you can change its location, but if you do, then you’ll have to change the WEB_SOCKET_SWF_LOCATION, due to an issue with Firefox (… for further information visit juggernaut git page).
Juggernaut serves every file necessary for running by default, so you can leave them on the server where Jaggernaut is installed and configure everything in your client (mainly due to Firefox) in order to avoid adding extra files to your project.
Add to your view this line:
<script src="http://localhost:8080/application.js" type="text/javascript" charset="utf-8"></script>
Note : you can add this file in another way or eventually add it to your project if you want.
Inside another script tag:

var jugger = new Juggernaut;
** Connection events provided by Juggernaut
Juggernaut provides you with three different events : Connect, Disconnect o Reconnect.
jugger.on("connect - disconnect - reconnect", callback)
You can use this events to implement whatever function you want to execute, i.e. alerting when a client has connected:
jug.on("connect", function() {alert("I'm connected!!");});
At this point you have the connection of your client ready, you can test it, you have to start Juggernaut. * First run redis :
./redis-server redis.conf

(whereever you have installed it) *

Then go to the folder where you’ve downloaded the server to and run juggernaut:
node server.js
Let’s chat!
Now that we have everything going, would be a good time to start chatting.
First you need to subscribe to a channe. Inside the channel you’ll be able to connect and user messages scope is restricted to channel.
Then :
 jug.subscribe("name_or_channel_id", function(data) { .. here you'll handle all messages coming from channel ... })
Clarifying a bit… with this function we subscribe to the channel and can pass a function as a parameter to handle data coming from it, i.e. any user’s messages, let’s give an example:
First you need to have a div tag with an id (id_div), what you want is to append a list element containing message content to the div element everytime someone sends a message.
jug.subscribe("name_or_channel_id", function(data){
var li = $("<li />");
li.text(data);
$("#id_div").append(li);
});
You can have a div or textearea element, adding text to a textarea element is relatively simpler, it’s enough to do

textarea.value += (data + "\n");

but you’ll lose customizing power. li elements can be enriched with style, making the chat more attractive.

You’ve received data and added to a div element, but you’re still unable to send data. Let’s setup a form:
<% form_remote_tag(:url => path_to_send_message_method, :success => "$('#msg_body').value=''" do >
<= text_field_tag 'msg_body', '', :size => '50' >
<= submit_tag 'Send Message' >
<% end %>
And the method :
def send_message
Juggernaut.publish("name_or_channel_id", parse_chat_message(params[:msg_body], current_user))
end
parse_chat_message? … Yes, before publishing data, you can process it and why not modify it a bit.
def parse_chat_message(msg, user)
return "#{user.login} says: #{msg}"
end
We are sending information to Juggernaut with this format : ‘usuario says: something’
Done!, you have your server up and running, and know how to send and receive data, there’s nothing else to try.
Extras:
Private chat case :*

You can’t call a chat a chat if you can’t have a private conversation with someone. A good way of implementing this, is subscribing your users to a particular chatroom identified by user’s id. Simple add another subscribe:
 jug.subscribe("name_or_channel_id", function(data){ .. handle private message .. }
The receiving user must be able to subscribe to your chat and send messages to you.
To achive that, you should write a function that when you click on the user you want to send a private message to, subscribes to its chatroom and allows you to send messages to the user. This can be implemented in many different ways! You’ll have to simply make your choice according to your needs!

Rails 3: New features & Changes

Posted by Michel Golffed on November 18, 2010

In this post I’ll show you some basic examples about the new features and changes of the web framework Rails 3, for this I’ll use two models: User and Task, having a relationship between them where a User has_many :tasks.

ActiveRecord finder methods

Let’s start by finding the five most recently created users:

Rails 2

User.find(:all, : order => "created_at desc", :limit => 5)
What’s new about this method call in rails 3?
Rails 3 looks at the hash of options that is being passed to find(:all, : order, and :limit) and replace each item in the hash with an equivalent method.

New API methods:

where, having, select, group, order, limit, offset, joins, includes, ...
So, in Rails 3 this becomes:
User.order("created_at desc").limit(5)
Let’s continue with this second example:
Rails 2:
User.find(:all, :conditions => ["created_at <= ?", Time.now], :include => :tasks)
Rails 3:
User.where("created_at <= ?", Time.now).includes(:tasks)
In this example the “where” method substitutes the :conditions parameter.

Named Scopes

Changes to named_scopes in Rails 3:
User model in rails 2 with two named scopes:
class User < ActiveRecord::Base
named_scope :active, :conditions => '!is_deleted'
named_scope :south_american,
:conditions => ["nationality IN (?)", Nationality::south_american_countries]
end
The same in rails 3 would be:
class User < ActiveRecord::Base
scope :active, where('!is_deleted')
scope :south_american,
where("nationality IN (?)", Nationality::south_american_countries)
end
Note that the method that we use to define as named_scope has become to just “scope”. Also, we no longer pass the conditions as a hash but, as with find, we use methods.
Chainability

Another new feature is the ability to build up scopes. If we want to create a scope called “recent”, that will return the most recently created active south american users ordered by their creation date, we can do so by reusing the two scopes we already have.
Chaining together the two scopes we already have and add an order method to create the new scope, is all we need to do.
Here is the result:
scope :recent, active.south_american.order("created_at desc")

ActiveRecord Validation

Separate validations in Rails 2
validates_presence_of :email
validates_uniqueness_of :email
validates_length_of :email, :maximum => 30
All validations together for a field in Rails 3
validates :email, :presence => true,
:uniqueness => true,
:length => {:maximum => 30}
Hope you enjoyed it, some other features of Rails 3 will be published on upcoming posts.

Bullet: a gem to help reduce N+1 queries

Posted by Lucía Escanellas on November 11, 2010

Bullet is a plugin written by Richard Huang, that helps reducing the number of queries an application makes. It was first posted on 2009, but it is still a pretty useful gem to monitor your application for performance improvements.
It has several ways of notifying problems: by Growl notifications, JavaScript alerts by default, and even using XMPP too. Additionally, it saves on its own bullet.log the exact line and stack trace of what caused the alert, and if you want to, it can also write to the application log.

The project is on GitHub: http://github.com/flyerhzm/bullet

You are probably familiar with the N+1 query and cache counter problems, so let’s look how Bullet will detect these by monitoring the database queries.

The N+1 query problem

Suppose we have our application with accounts having many rate plans:

class RatePlan < ActiveRecord::Base
  belongs_to :account
end

If we iterate over the rate plans, accessing rate plans attributes, like:

RatePlan.all.each {
  |post| puts "#{rate_plan.name}, by #{rate_plan.account.name}"
}

Will be using N+1 queries:

  • one query to get all the rate plans
  • then, for each rate plan, one query to get the corresponding account.

(This means that if we have 1000 posts, we’ll be doing 1000+1 queries)

By using the :include option, we can retrieve the rate plans and their corresponding accounts on the same query:

RatePlan.find(:all, :include => :account).each {
   |post| puts "#{rate_plan.name}, by #{rate_plan.account.name}"
}

By detecting if we forgot to use eager loading or a counter cache, Bullet can save time looking for problems on the fly.
For example, Bullet will show this message:

N+1 Query Detected Message

We have to be careful not to abuse the :include option. If the rate_plans table is big enough, it could take too much server memory. Also, we could end up with big, slow requests, or getting from the server a lot of data that won’t be used. Bullet will show a message if it detects an unused eager loading.

Cache counters

Cache counters is another improvement in a one-to-many relationship. Because the _has_many_ relationship defines an attribute that is a collection, if we use the size property on this attribute, it will trigger a select count(*) on the child table. This is generally acceptable, except when we are using frequently count and we end up going to the database unnecessarily.
In order to avoid that, we can use counter caching: Active Record will maintain for a parent table the number of child references. Bullet also shows a message if it finds a cache counter is needed.

Configuration

You have to first install the gem, by adding it to the Gemfile, or by installing manually:

sudo gem install bullet --pre

The next thing is to add some configuration to the development environment. Bullet won’t do anything unless you configure it explicitly, and also note that it’s not a good idea to configure it on the production environment, because on that case your users would also receive those N+1 query alerts.

Configuration allows Growl notifications, and sending messages by XMPP (Jabber), but since the default JavaScript alerts are good enough for me, I configured it like this:

config.after_initialize do
  Bullet.enable = true
  Bullet.alert = true
  Bullet.bullet_logger = true
  Bullet.console = true
  Bullet.growl = false
  Bullet.rails_logger = true
  Bullet.disable_browser_cache = true
end

Note the last option, because disabling browser cache can save you some trouble on some configurations. In any case, if Bullet is not working, try first disabling browser cache.

With this configuration, it will show a JavaScript alert, the same message on the console, and the detail and stack trace on the bullet.log.