Tuesday 25 December 2012

Rails helpers you should be familiar with

AssetTagHelper

- helps you link html page with various assets as javascripts, stylsheets, images...
- useful if you have assets saved on different servers

javascript_include_tag(*sources)

- creates a script tag for each of the provided sources
- tarts from public/javascripts
- uses javascript_path to calculate the path to the javascript file

stylesheet_link_tag(*sources)

- creates a stylesheet link tag for each of the provided sources
- starts from public/stylesheets
- stylesheet_path caluculates locat

image_tag(source, options = {})

- creates a image tag for the provided image location
- image_path caluculates location
- aditional HTML params(align...) can be passed by using options hash

CaptureHelper

- very useful for reusing page parts at different locations by using yield

content_for(name, &block)
- saves the content of the block and provides it for later usage
- useful for action menus or similar components used at different
places but with similar functions

content_for?(name)

- checks weather we'll get any context by using content_for 

DateHelper

- useful for creating select tags for different date combos(full date, only year, time ...)
by using methods like select_date, select_time ...
- includes distance calculation methods like distance_of_time_in_words:
  distance_of_time_in_words(Time.now, Time.now + 5.minute) => "5 minutes" 

FormHelper

- helps with craeating forms closely related to Active Record models linked with a view

form_for(record, options = {}, &proc)

- creates a form and a scope around a specific model object that is used as a source for field data.
- accepts params :url (location where form is submitted to), :html (standard attributes) and :builder (custom form builder e.g. Formtastic)
- uses automated resource identification to configure submit location
- default protection from CSRF attacks
- support for multiple objects update by using square bracket notation => form_for "user[]" do ...

fields_for(record_name, record_object = nil, options = {}, &block)

- creates a scope arround a specific model object without creating tags
form_for @user do |f|
.....
fields_for @user.settings do |s| => params[:user][:settings]

field builders

check_box, email_field, file_field, hidden_field, label, number_field, password_field, radio_button, range_field, search_field, submit, telephone_field, text_area and text_field 

FormTagHelper

- same results as FormHelper but without a link to Active Model instance

NumberHelper

- helps with formatting numbers understandable to user

number_to_currency(number, options = {})

- number_to_currency(12345.60) => $ 12,345.60

number_to_human_size(number, options = {})

- number_to_human_size(1234) => 1.2 KB

 

TagHelper

content_tag(name, content_or_options_with_block = nil, options = nil, escape = true, &block) 

- programmatically creates a HTML block by using provided tag name and content
- you can also pass a block to create more complex content

tag(name, options = nil, open = false, escape = true)  

-creates tag programmatically

 

TextHelper


pluralize - attempts to pluralize singular world

 

UrlHelper

- methods for generating links

button_to(name, options = {}, html_options = {})

- creates a form submit button directed at the URL from options parameter
- used for all resource modifier actions to prevent unwanted changes

link_to(*args, &block)

- creates a link for the given name and options
- options are processed by url_for method which returns URL for the provided options

Tuesday 18 December 2012

Rails attribute serialization

Switching to Postgres after working for over two years on Hbase is quite a change. The ability to use ActiveRecord feels like getting a nuke. Searches, orders, associations, you name it. But on the other hand, one of the things that felt missing was serialization of which I got so accustomed. It just felt wrong to create separate table for users settings. Why not just store it in the User table?!

Well, Active Record has an option for that. Attributes can be marked as serializable and stored in desired format in the database. Default format is YAML, but you can pass Array, Hash or Class of your own. I'll use Hash:
# model
class User < ActiveRecord::Base
  serialize :settings, Hash
end

# controller
def create
  @user = User.new(params[:user])
  ......
end
Unless a value has already been set for the settings attribute, this won't work since its not initialized.
We can fix that with after_initialize callback:
# initialization callback
def after_initialize
  self.settings ||= {} 
end
Another thing we have to do is to make the form add settings parameter around the items we want to set. We are creating a new object with mass assignment so we need to tell the new method that these attributes are part of the settings hash not of the User model. For this this purpose fields_for helper comes in handy:
# form view
<%= f.fields_for :settings do |setting| %>
  Send newsletter <%= setting.check_box :send_newsletter %>
<% end %>
When we save the user and look in the database we should see serialized settings parameter saved as settings: {"send_newsletter"=>"1"} .
I think this is quite useful for avoiding creating all new table,  joins and so on....