miércoles, 13 de mayo de 2009

ruby on rails, googlebot(at)googlebot.com, No HTTP_REFERER, canonical and consistent websites



When you have an exception from the system, something like:


Subject: [ERROR] ships#flag_choice (ActionController::RedirectBackError) "No HTTP_REFERER was set in the request to this action, so redirect_to :back could not be called successfully. If this is a test, make sure to specify request.env[\"HTTP_REFERER\"]."


A ActionController::RedirectBackError occurred in ships#flag_choice:

No HTTP_REFERER was set in the request to this action, so redirect_to :back could not be called successfully. If this is a test, make sure to specify request.env["HTTP_REFERER"].




Is your chance to make a better website, a browseable website for robots.



Here you have:

app/controllers/application.rb

before_filter :load_url_back

def flag_choice
set_locale(params[:id])
session["lang"] = "#{params[:id]}"
#redirect_to :back
redirect_to params[:url_back]
end

def load_url_back
@url_back = "http://" + request.env["HTTP_HOST"]
+ request.env["REQUEST_URI"]
end


apps/views/layouts/application.html.erb

<%= link_to(image_tag('ingles.png'),
:action => 'flag_choice', :id => 'en_EN',
:url_back => @url_back ) %>
<%= link_to(image_tag('esp.png'),
:action => 'flag_choice', :id => 'es_AR',
:url_back => @url_back ) %>





Now we have consistent links that can be saved in any place, and consulted without history of browser navigation. This makes your links independent from where you came from.
And in the controller you are working in a request that just need canonical information from the HTTP Request.

domingo, 10 de mayo de 2009

viernes, 8 de mayo de 2009

ruby on rails, ActiveResource::Base, paginate, WillPaginate, RESTful xml resource and paginate

This sample assume that you have a service in the server that respond .xml


class NoteIntranet < ActiveResource::Base
self.site = INTRANET_CREDENTIALS[:site]
self.element_name = 'note'
cattr_reader :per_page
@@per_page = 20
def self.paginate(*args)
options = args.pop
@@per_page = options.delete(:per_page) || @@per_page
WillPaginate::Collection.create((options.delete(:page) || 1), @@per_page) do |pager|
all_elements = self.find(:all, options)
result = all_elements[pager.offset, pager.per_page].to_a
# inject the result array into the paginated collection:
pager.replace(result)
unless pager.total_entries
# the pager didn't manage to guess the total count, do it manually
pager.total_entries = all_elements.size
end
end
end

end


In the controller you may have conditions that are defined in the service, an example is a filter:


@notes = NoteIntranet.paginate(:page => params[:page], :params => { :title => params[:title] })


In the server service, in the controller you have:


@notes = Note.paginate(:page => params[:page], :conditions => ["title like '%?%'",params[:title]] )


This idea came from Gasper - Luis Guardiola