Showing posts with label ruby. Show all posts
Showing posts with label ruby. Show all posts

Wednesday, June 13, 2012

The rvm sudo gem install gotcha

The title of the post says it all.  Ruby Version Manager (RVM) is handy for quickly switching between different versions of ruby, but if you have been using a system installation, your muscle memory may have you typing this to install a gem:
sudo gem install

It doesn't work as you might expect with rvm. It installs the gem in the gem repository of the system ruby.

I got caught out by this, and I hope others can learn from my mistakes.

So if you have done:

rvm use 1.9.2

Then to install a gem, you should go

gem install


Saturday, June 9, 2012

BrowserID with Ruby and Sinatra

I have been playing with Mozilla's browserid (soon to be called Mozilla Persona), which is a service to manage authentication with your email address as the login. I am using the ruby gem called sinatra/browserid to access it. When moving my code to a new computer, I started getting these errors:
application error TypeError at /_browserid_assert can't convert nil into String file: common.rb location: initialize line: 148
It seems to be a problem with a change in ruby 1.9.3 http.post which returns a single res instead of a res, body pair. I found a fork of the gem that fixes this problem. These are the commands to install the forked gem from github:
git clone https://github.com/passcod/sinatra-browserid.git gem build sinatra-browserid.gemspec sudo gem install sinatra-browserid-0.3.1.gem
(omit the sudo if you use rvm).

Thursday, May 21, 2009

ActiveRecord Oracle Enhanced adapter with legacy tables - primary key triggers.

I was using active record, Inserting data into tables that have triggers set up to create the primary key from a sequence of numbers. The oracle adapter doesn't support this 'out of the box'.

When I read about the approach that the oracle adapter takes to auto incrementing primary keys, my first thought was that it was a bad idea. Why wouldn't you use the 'standard' approach of creating a sequence for the primary key, and writing a trigger to set the primary to the next value of the sequence upon creation of a record? This ensures that the same policy is used, whether a stored procedure or an ad-hoc insert is used. (I am talking about the fact that the oracle adapter creates its own primary key using #next_sequence_value in oracle_enhanced_adapter.rb.)

It's probably just me; I am coming from the viewpoint of someone who has spent the last 3 years working with oracle databases using plsql stored procedures to program much of the logic. I already have the sequences (which ActiveRecord migrations create automatically). I also have triggers, which interfere with the adapters behaviour.

To someone who just wants to move their rails application onto an oracle database, the approach taken by the adapter makes more sense. Also no oracle-specific code (outside of the adapter itself) has to be used.

I can imagine an adapter for data definition commands (eg table creation), encapsulating this code, but as far as I know, rails migrations are fairly basic when it comes to setting up a database. They require extra setup for foreign keys, for example.

I tried searching for a solution in the blogosphere, this post mentions this problem, but is actually about an issue with LOBs, which is solved in a later version.

Raimonds Simanovskis, the maintainer of the adapter, blogged about custom activerecord methods for legacy oracle databases.
It didn't help, because my knowledge of how activerecord adapters work was pretty limited at the time. (It is only slightly less limited now).

I posted to the "oracle-enhanced" google group and Raimonds was kind enough to improvise an 'ugly' solution. I tried it out and it seemed to work.

I added the code to the end of the apps config/environment.rb:
class ActiveRecord::Base
set_create_method do    
quoted_attributes = attributes_with_quotes
conn = connection.raw_connection
cursor = conn.parse <<-EOS
BEGIN
INSERT INTO #{self.class.quoted_table_name} (#{quoted_column_names.join(', ')}) 
VALUES(#{quoted_attributes.values.join(', ')})
RETURNING #{self.class.primary_key} INTO :id;
END;
EOS
cursor.bind_param(':id', nil, Integer)
cursor.exec
id = cursor[':id']
cursor.close
id
end
end

What does this code do? It replaces the default active record create method with a method that sends a small pl/sql
script (the bit between BEGIN and END) which gets the new primary key. Note this works even if you change the name of
the primary key in your model using set_primary_key.

This also requires the plsql gem to be installed, which seems to be required for the adapter anyway.

There is one major shortcoming; this patch causes inserts to only work with tables that have an auto-increment sequence and trigger combination set up.

Ideally, this code could be incorporated into the adapter, and a setting could be used to switch it on or off. I don't know if there would be much demand for it, though.

Friday, March 27, 2009

Rails js.rjs Templates vs the Nonexistent js.erb Template.

I wanted to add a javascript file to a rails project, but I wanted the javascript page to contain some dynamic content from activerecord. Normally you would just include the dynamic content in the web page, but I wanted to enable the inclusion of my javascript into someone elses page. (Nothing underhand, this would be done voluntarily).

At first I tried to save the javascript as an .rjs file. However this is not the correct place for a plain javascript file. Rjs is a template language that describes the changes to the dom of a page using ajax. The rjs is converted to javascript which makes use of the prototype library.

It would make sense to save the javascript file as type js.erb within the view, but this is not recognised by rails. I can understand why this is not supported, because it's a fairly obscure usage.

The workaround is to simply to save your javascript file as an html.erb file, and set the appropriate content type in your controller.

Lets suppose our javascript file want to write out the information from a table stored using ActiveRecord. In this example, there is a MyInfo model class, with an attribute called description.

// controller
def blah
@myinfo = MyInfo.find(:first)
response.content_type = "text/javascript"
render :layout => false
end

The javascript file would be something like this:

// blah.html.erb (javascript file with erb template)
Document.write("<div><%= @myinfo.description %></div>");


The javascript file would then be loaded from a regular web page, for example:

// web page using the javascript file.
<script type="text/javascript" src="/mycontroller/blah">
</script>