Old Emmanuel Oga's Weblog (new one is at www.emmanueloga.com)

How to spec a rails plugin?

Posted in rails, rspec, Uncategorized by emmanueloga on junio 25, 2009

Basically, the same way you spec a rails application.
The cool trick is you take advantage of the spec_helper.rb of by loading it in the spec_helper of your plugin.

# ../vendor/plugin/YOUR_PLUGIN/spec/spec_helper.rb
begin
  # load your main app spec_helper
  require File.dirname(__FILE__) + '/../../../../spec/spec_helper'
rescue LoadError
  puts "You need to install rspec in your base app"
  exit
end

I took this idea from Pat Maddox’s rspec-plugin-generator. You can use that generator to generate the basic plugin boiler plate for you.

The caveats are, you need to have rspec installed on your main app and you need to actually have the plugin installed in a rails application to test it. In any case, this works for my current needs.

For more info see this post.

Anuncios

Locos por Rails Conference in Buenos Aires, Argentina

Posted in people, rails, ruby by emmanueloga on enero 23, 2009

Badge Locos X Rails Conference

Por fin!, una conferencia de ruby y rails en Argentina! La misma se realizará el 3 y 4 de Abril en la Universidad de Palermo, C.A.B.A. Estan cordialmente invitados. La inscripción no ha empezado todavía, pero si pueden mandar sus propuestas para disertar en la misma.

Locos Por Rails Conference 2009 will be held on April 3rd and 4th in Buenos Aires, Argentina. Registration is not open yet, but the call for papers is already open. Send yours!

Tagged with: , ,

Reunion Ruby Argentina del sábado pasado

Posted in rails, rspec, ruby by emmanueloga on diciembre 6, 2008

Con tan solo una semana de demora :), una pequeña descripción de la reunir del sábado pasado con los muchachos de #ruby-ar.

Ricardo Markiewicz consiguió el aula en la facultad de ingeniería, donde estuvimos muy cómodos a pesar del calor, y  fue el “maestro de ceremonias”.

Matías Pablo Brutti nos habló muy brevemente acerca de uno de los proyectos en los que trabaja, sicherheit. Ojalá Matías pueda dar una charla más prolongada acerca de seguridad en aplicaciones web en alguna próxima reunión :).

Luís Lavena nos mostró rake-compiler, una gema que contiene tareas de rake que ayudan a cross-compilar código. Con rake-compiler es muy sencillo compilar extensions de ruby que funcionen tanto para un sistema operativo basado en unix como para Windows, ahora que el one click installer utiliza mingw como compilador. Luís utilizó cucumber para planear y testear la funcionalidad de su gema. Además, mostró algunas deficiencias que a veces cometemos por “vagancia”, como hardcodear paths a herramientas del sistema en los scripts de instalación. Además, Luís se incluyo el modulo acts_as_photographer y sacó las fotos que pueden ver más abajo.

Pedro Visintin invitó a Pelle Braendgaard, desarrollador de la gema  http://oauth.rubyforge.org/, quien nos habló un poco de porque querríamos utilizar OAuth para compartir información sensible de los usuarios de nuestras aplicaciones.

Además, Pedro dió su propia charla: “Como ser freelancer y no morir en el intento”. Nos habló de los riesgos que corremos como freelancers y como prepararnos para los mismos. Nos animó a no tomar nuestra profesión como un trabajo, sino mas bién disfrutar de lo que hacemos, y nos recomendó este libro. También, he aqui los slides de su charla.

Rafaél Bidegain, representando a CaFeLUG,  trajo algunos libros que se sortearon al final de la reunión, junto con una remera que trajo Pedro. Obviamente yo no me gane nada jajaja.

Como resumen todo muy bueno, ¡que se repita!

Tagged with: ,

require or not article on Space Vatican blog

Posted in rails, ruby by emmanueloga on noviembre 14, 2008

This article is so cool I want to recommend it, and also keep it linked here (hmmmm, I really need to resurrect my delicious account… :p)

http://www.spacevatican.org/2008/9/28/required-or-not

Tagged with:

Handling URIs in ruby a walk in the park? Don’t think so….

Posted in rails, ruby, Uncategorized by emmanueloga on octubre 17, 2008

I got sick an tired of juggling around with String urls and URI objects just to get a correct URI for http GETting, POSTing, etc…

For example, if you

Net::HTTP.post_form URI(“www.somewhere.com”)

you get an error…. but if you

Net::HTTP.post_form URI(“www.somewhere.com/”)

(notice trailing slash) you don’t… Boring stuff. The URI lib does provide a normalize method, but it does not always add the trailing “/”. For consistency I wanted normalize to add the trailing slash always. Update: seems like my “consistency” politic is not correct…. Oh, well… at least google does not like it. 🙂 I’m updating my Gist to remove that behavior…. Off course! Adding a trailing slash means you are looking for a directory and not for a resource, so you can’t go berserk adding trailing slashes in all your urls :p

But, the most boring stuff is joining uris and adding query params to them… This should be simple, right?:

uri = URI("something.com/?some=params")
uri.query = "other=params" # WRONG, previous params are overwritten
uri = URI("something.com/")
uri.query << "other=params" # WRONG, previous query is nil
uri = URI("something.com/?some=params")
uri.query << "other=params" # WRONG, params should be joined with & char...
&#91;/sourcecode&#93;

We need to <a href="http://github.com/jnunemaker/httparty/tree/master/lib/httparty.rb#L113">juggle with the URI object</a> to get the job done. More boring stuff. I wrote<a title="Joining an nomrmalizing URIs in ruby" href="http://gist.github.com/17342"> two simple methods to handle these problems</a>. Now I won't have to manually tweak those urls again... never more! (I hope :-).


  describe NormalizeURI do
    it "should add scheme and final / to an uri" do
      NormalizeURI("www.yahoo.com?something=true").to_s.should == "http://www.yahoo.com/?something=true"
    end
  end

  describe JoinURI do
    it "should join a string, an uri and additional query params" do
      one = URI("www.yahoo.com?uno=dos")
      two = URI("/peteco/carabal?tres=4&cinco=seis")
      result = "http://www.yahoo.com/peteco/carabal/?uno=dos&tres=4&cinco=seis"
      JoinURI(one.to_s, two, :more => :params).should.to_s == "#{ result }&more=params"
    end
  end

This is such small stuff I don’t think a gem for this would be cool…. maybe later (no gemspec fighting yet hehe). And yes, because I’m lazy I’m using active_support this time…. I’m using this inside rails anyways.

Tagged with: , ,

Meeting RubyArg (nos visitó Marcel Molina Jr., que calidad!)

Posted in people, rails, rspec by emmanueloga on agosto 18, 2008

El pasado Viernes Pedro Visintin organizo una reunion de railers, con la presencia de un invitado deluxe: Marcel Molina Jr.! Estuvo todo muy bueno, gracias Pedro por organizar el encuentro. No solo charlamos de temas muy interesantes, sino que tambien aprendi un par de lecciones fotográficas:

Diego se va

Diego se va

Otra vez la misma foto

Otra vez la misma foto

No entramos todos

No entramos todos

Ahora si entramos todos

Ahora si entramos todos

Tagged with: , , ,

Liquid Coolness

Posted in rails, ruby by emmanueloga on julio 26, 2008

For the unaware Liquid is “a ruby library for rendering safe templates which cannot affect the security of the server they are rendered on” by Tobias Lütke.

Although Liquid has been around for a long time now, I had the opportunity to use it just recently. I found its source code very informative, so I thought of sharing my findings.

You don’t need rails at all to use liquid. Here is a very minimal script for rendering a liquid template:

require "rubygems"
require "liquid"
Liquid::Template.parse("hello {{ place }}").render( "place" => "world" ) # => "hello world"

Markup

The documentation shows two types of markup:

  • Output, surrounded by {{ two curly brackets }} (similar to the erb <%= %> markup )
  • Tags, surrounded by {% a curly bracket and a percent %} (similar to the erb <% %> markup )

Important note: liquid does NOT allow ruby code inside the markup. Example:

Liquid::Template.parse("{{ 1 + 2}}").render # => ?

What would you expect this example to output? Well, Liquid will parse the string “1” and ignore everything else. This very restriction is what makes Liquid so safe.

Tags and Blocks

Some tags work as method calls:

'{% a_tag "some param" %}' # => calls "method" a_tag with param "some_param". 

Some standard Liquid tags that behave like this are: “cycle”, “assign”.

Others tags capture what’s between the beginning and the end of the call:

<<-TEMPLATE
  {% a_block_tag "some param" %}
    {{ something }}
  {% enda_block_tag  %}
TEMPLATE
&#91;/sourcecode&#93;

<p>
Example block tags: "comment", "for". In these cases the end tag is always equal to the opener but with the string "<strong>end</strong>" prefixed. 
<p>

<p>
You can find more information about the available tags in <a href="http://github.com/tobi/liquid/wikis/liquid-for-designers">liquid's wiki page for designers</a> and eventually, by looking at the <a href="http://github.com/tobi/liquid/tree/master/lib/liquid/tags">source of the standard tags</a>.
</p>

<br>
<h2>Filters</h2>

<p>
Filters can be applied on output tags:
</p>


  template = '{{ "some string" | upcase }}'
  Liquid::Template.parse(template).render # => "SOME STRING"

In the previous example, the filter is named “upcase” and is invoked using the pipe syntax.

Filters can be chained up:

  template = "{{ 'some text'  | upcase | truncate, 7 }}"
  Liquid::Template.parse(template).render # => "SOME..."

A non existent filter in the chain will be just skipped:

  template = "{{ 'some text'  | non-existent-filter | upcase | truncate, 7 }}"
  Liquid::Template.parse(template).render # => "SOME..."

Another interesting thing is that you can use assigns (variables) as parameters for the filters:

  template = "{% assign length = 5 %}{{ 'some text'  | upcase | truncate, length }}"
  Liquid::Template.parse(template).render # => “SO...”

You can take a peek at the standard filters in the documentation.

Some Internals

There’s a page on the wiki which describes some aspects of the Liquid’s API and how to extend the system.

Liquid templates are handled in two stages: first parsing, then rendering. A template string that has been parsed just once can be rendered many times with different assigns in its context data:

parsed_template = Liquid::Template.parse( "some {{ my_var }} template" )
parsed_template.render( "my_var" => "nice" ) # => some nice template
parsed_template.render( "my_var" => "cool" ) # => some cool template

In parsing stage the template string is tokenized according to the markup rules. Some regular expressions are used for this purpose. In this stage, Liquid::SyntaxError exception may be raised if an error is found.

The Context

In the rendering stage, an instance of Liquid::Context class is used for several things: storing “assigns” (local variables), “registers” and “scopes”.

Assigns

The context’s assigns (local variables) can be initialized when calling “render” method on the parsed template. We need to supply a hash for this purpose:

parsed_template = Liquid::Template.parse( "{{here}} have been {{are}}" )
parsed_template.render( Hash[ "here" => "the assigns", "are" => "initialized" ] ) 
# => "the assigns have been initialized"

Providing assigns to the render method is not mandatory. It is also possible to modify the assigns using markup. In particular the “assign” tag does just that.

Scopes

More than one Hash is used when storing assigns: there will be one per scope. The context’s scopes are managed in an Array of assigns Hashes.

parsed_template = Liquid::Template.parse(<<-EOTEMPLATE)
  {{ var }}
  {% assign var = "end" %}
  {% for var in collection %}
    {{ var }}
  {% endfor %}
  {{ var }}
EOTEMPLATE
parsed_template.render("var" => "begin", "collection" => [1, 2]) # => begin 1 2 end

In this example, outside the “for” block, hello stores “begin”. At the time of the first output, the “upper” assigns Hash holds “begin” as the value of “var”. Later, the value of “var” is changed to “end” by means of the assign tag. But inside the for block, hello is assigned 1 and later 2. The final value is not overwritten because a new scope is created inside the “for” block.

You can’t give access to objects of arbitrary classes to end users. Due security concerns, only String, Numeric, Hash, Array, Proc, Boolean or Liquid::Drop are allowed by default. The final value rendered in the template is the result of sending “to_liquid” message to the resolved object. Liquid extends some of the ruby standard classes with that method.

Resolution will be performed by looking at the assigns hash at the “top” of the scopes array, and moving down the stack if the value can’t be found there. See Liquid::Context#find_variable(key) for the implementation details.

A Liquid “assign” tag may overwrite any previous value inside its scope.

Registers

Registers are passed in a hash to Context instances. Registers holds data related to the rendering of tags that will not be directly accessible by the end user, but still will be necessary for the functioning of a Liquid tag or block.

The registers are global to all tags and blocks in any scope. An example of registers usage can be found in the implementation of the “ifchanged” tag.

You can pass data to the registers in the call for render:

psd_templ.render({"var" => "..."}, :registers => { "some_data" => AnyClass.new }) 

Manipulation of the registers only makes sense if you are planning to use the data inside a custom Liquid tag or block. As an example, I have used registers to give Liquid tags access to rails session data.

In a following post I will talk about the different ways of extending Liquid.

Here are some interesting links related

This was also published here.

Using link_to, url_for, path methods from arbitrary places

Posted in rails, rspec, ruby by emmanueloga on mayo 30, 2008

This is one thing I always forget, so I will post it to have it as reference.

If you need to call url_for or path methods (e.g.: root_path) from outside a controller, a view or a helper (perhaps inside a class lying somewhere inside RAILS_ROOT/lib/**/*), you will need to:

include ActionController::UrlWriter

If you also want to use link_to, you will need to:

include ActionView::Helpers::UrlHelper
include ActionController::UrlWriter

I include the two modules as I will probably want to use path methods in my link_to. Also notice that the UrlWriter module comes after the UrlHelper module.

“But it does not work!” I can hear you scream… If you get a message like this:

You have a nil object when you didn't expect it!
The error occurred while evaluating nil.url_for
(eval):17:in `project_stories_path'

Fear not, you may not have included the files in the right order. That message will appear if you include ActionController::UrlWriter before including ActionView::Helpers::UrlHelper. Just stick to the order I show above and the message will disappear.

ActiveResource

Posted in ActiveResource, rails, rest, Uncategorized by emmanueloga on enero 21, 2008

I’m making my first contributions to rails. All of them deal with ActiveResource, a rails related library engineered to consume restful services.

It behaves more or less the same way as an ActiveRecord (even though it is NOT a replacement for ActiveRecords). With these in mind, I proposed these patches (not surprisingly some of them where already informed issues in the rails trac):

  • Ticket 7308 Addition of update_attributes method
  • Ticket 10537 Addition of new_record? method
  • Ticket 9862 Modificate behavior for #new (initialize) , patch not provided yet (waiting for opinions)

If this patches where applied, one would be able to seamlessly replace an ActiveRecord with an ActiveResource in a scaffolded CRUD, restful web app (I used rails 2.0.2 and the scaffold provided with rspec 1.1.1 rspec_scaffold generator. Not sure if it works the same way as “scaffold” generator on rails).

Tagged with:

Ubuntu gutsy problem number two: ruby script/console fails to start (readline)

Posted in rails, ubuntu by emmanueloga on noviembre 29, 2007

Just for the record, number problem one was to set up mongrel_cluster on init.d.

Soooo. Now “ruby script/console” fails with a “require ‘readline’ failure” or something. The problem was that, for some reason, when i built the ruby interpreter (1.8.6) the readline extension was not built and installed. ruby’s readline extension comes with the standard ruby distribution. So, i did a:

  • locate readline” (probably you will need a “sudo updatedb” before, or better just look for the source code of your ruby interpreter where you know it is. You know that, right? 🙂
  • Went to the directory where your ruby source code lives, subdirectory ext/readline. In my case: “cd ~/packages/ruby-1.8.6-p110/ext/readline
  • ruby extconf.rb” –this one generates the makefile for the library
  • make
  • sudo make install“.

In ubuntu you’ll problably need libreadline5 and libreadline5-dev _before_ running make:

sudo apt-get install libreadline5 and libreadline5-dev

Now “ruby script/console” should work.

Tagged with: , , , ,