The Dev Blog

Putting Family Management on Rails!

Ruby and XMPP/Jabber Part 2: Logging in and sending simple messages

Posted by Guy Naor Sat, 14 Oct 2006 15:34:00 GMT

Time to get down to some sample code!

In this part I will show how to log in to a Jabber server and send a simple message. This is the basis of everything else, and will give you something nice to start with. After all, sending messages is the most common use for Jabber.

Installation

Get the code from here, unpack it and then run ./setup.rb from the directory you open the archive to. YOu can also get the gem and install it locally. As it's pure ruby, there aren't any complications with it.

What we will need?

To start, get irb going as we'll do it interactively so we can get immediate results. You will also need a Jabber account you can login to, and another account to send messages to. You could send to the same account, actually, but it's nicer with a second one.

For this session, I will be using my account at DreamHost - they provide Jabber as one of the features of the account, which is pretty cool. YOu can also setup one of your own, but it's beyons the scope of this post.

Server: yeush.com

User: test

Password: test (don't worry, I'm not this crazy, this is a fake password...)

And we'll interact with another accounts (that has the test account as a buddy that can connect to): test_with_me@yeush.com.

Now in irb, make sure we have xmpp4r included:

irb
require 'xmpp4r/client'
include Jabber # Makes using it a bit easier as we don't need to prepend Jabber:: to everything

Logging in

To start any communication with a Jabber server, we need to first log in to the server:

# Jabber::debug = true # Uncomment this if you want to see what's being sent and received!
jid = JID::new('test@yeush.com/Testing')
password = 'test'
cl = Client::new(jid)
cl.connect
cl.auth(password)

That's all it takes to login, really! Now for some explanations. The jabber system is made of a collection of servers that can be either stand alone, or connected to each other (called open federation). Each entity connecting to the network must have a unique ID, called a JID (Jabber ID). The id is made up of the user name, server the user is on and an optional resource. The resource is the part after the /, in this case /Testing. The resources can be arbitrarily named, and allow the same person/entity to be connected and talking from many places at once, while still knowing where to send replies back to.

Now that we are connected, let's do something with it...

Sending a simple message

Most of what we want to do in a Jabber session is send messages. So let's get one going:

to = "test_with_me@yeush.com"
subject = "XMPP4R test"
body = "Hi, this is my first try from XMPP4R!!!"
m = Message::new(to, body).set_type(:normal).set_id('1').set_subject(subject)
cl.send m

What did we have here? We assigned a few parameters, created a new message object, and had the client send it. subject is mostly ignored by clients. Very few will show it. body is the plain text message you want to send. *to* is well, the to.

A message is simple an REXML document, and the calls to setid('1') and settype(:normal), set those values in the message element. :normal is the message type. Look in the documentation for all possible types. We will be using :normal and :chat. id is used to identify the message, and can be anything. Usually it's an advancing counter, and it can also include letters and underscore.

After we have the message constructed, we let the client send it. Like I explained in the first part, the whole XMPP protocol is based on XML documents being sent and received. You can type m.to_s in irb to get the document representation. Here is how the message looks in XML:

<message type='normal' id='1' to='test_with_me@yeush.com'>
  <body>Hi, this is my first try from XMPP4R!!!</body>
  <subject>XMPP4R test</subject>
</message>

Go and play with that a bit, and on the next installment we'll see how to add rich-text to the messages (hint: adding it to the body won't work - you need a special html element for that).

See you next time...

Posted in ,  | no comments | no trackbacks

del.icio.us:Ruby and XMPP/Jabber Part 2: Logging in and sending simple messages digg:Ruby and XMPP/Jabber Part 2: Logging in and sending simple messages spurl:Ruby and XMPP/Jabber Part 2: Logging in and sending simple messages wists:Ruby and XMPP/Jabber Part 2: Logging in and sending simple messages simpy:Ruby and XMPP/Jabber Part 2: Logging in and sending simple messages newsvine:Ruby and XMPP/Jabber Part 2: Logging in and sending simple messages blinklist:Ruby and XMPP/Jabber Part 2: Logging in and sending simple messages furl:Ruby and XMPP/Jabber Part 2: Logging in and sending simple messages reddit:Ruby and XMPP/Jabber Part 2: Logging in and sending simple messages fark:Ruby and XMPP/Jabber Part 2: Logging in and sending simple messages blogmarks:Ruby and XMPP/Jabber Part 2: Logging in and sending simple messages Y!:Ruby and XMPP/Jabber Part 2: Logging in and sending simple messages smarking:Ruby and XMPP/Jabber Part 2: Logging in and sending simple messages magnolia:Ruby and XMPP/Jabber Part 2: Logging in and sending simple messages segnalo:Ruby and XMPP/Jabber Part 2: Logging in and sending simple messages

Ruby and XMPP/Jabber - a Multi Posts Series, Part 1

Posted by Guy Naor Tue, 10 Oct 2006 20:24:00 GMT

Instant Messages is one of the most common apps running on people's desktops. And they have the nice feature of popping up when a new message comes in. Exploiting this programmatically can open up a huge array of options.

In Famundo we added the ability to send alarms notifications to IM addresses. The initial implementation was easy and pretty trivial, given all the samples I found. When I wanted to go further, it became complicated, and there were no more examples to look at. Things like sending rich text messages, or talking to other IM services through XMPP gateways. I promise to show how to just that (and other things) in this series of posts.

I started with Jabber4R, but then realized it's not supported anymore, and all development is now done in XMPP4R. So I switched to it. It is a much more advanced library, and is pretty big. One of the prolems with it is the complexity. Part of it is the inherent complexity of the XMPP protocol. (Though I read somewhere it's simple, don't believe everything you read...)

My goal in this series of posts is to guide you into using XMPP4R to send messages, subscribe to services, send queries, etc... I might get also into receiving messages, though I see it as less important for rails applications. We'll see how much time I have on my hands. If there's something specific you would like me to discuss - let me know.

So lets get starting!

XMPP is a messaging protocol based on XML messages passed between clients and servers. Better known as THE open source for instant messaging protocol/server, is also the protocol used by GoogleTalk. there are also public servers you can subscribe to and use freely. With the right gateways it will let you send messages to all the other major IM networks (AIM, ICQ, MSN and YM). You can read all about it here. The protocol is described in a large collection of RFCs/JEPs and as those usually are, it's a bit of work to decipher them. But I do recommend reading atleast some of them. Depending on what you are trying to achieve.

Another good option are the Jabber/XMPP related books. But be warned they are not that complete, and are not Ruby based. The two I have are Java based:

Programming Jabber

Instant Messaging in Java

The following installments will be:

Part 2: Logging in and sending simple messages to a Jabber/XMPP server

Part 3: Adding html to the messages

Part 4: Queries + Callbacks

Part 5: Presence, or here I am!

Part 6: Sending messages to proprietary networks (AIM, ICQ, MSN, YM)

Tune in for more....

Posted in , ,  | no comments | no trackbacks

del.icio.us:Ruby and XMPP/Jabber - a Multi Posts Series, Part 1 digg:Ruby and XMPP/Jabber - a Multi Posts Series, Part 1 spurl:Ruby and XMPP/Jabber - a Multi Posts Series, Part 1 wists:Ruby and XMPP/Jabber - a Multi Posts Series, Part 1 simpy:Ruby and XMPP/Jabber - a Multi Posts Series, Part 1 newsvine:Ruby and XMPP/Jabber - a Multi Posts Series, Part 1 blinklist:Ruby and XMPP/Jabber - a Multi Posts Series, Part 1 furl:Ruby and XMPP/Jabber - a Multi Posts Series, Part 1 reddit:Ruby and XMPP/Jabber - a Multi Posts Series, Part 1 fark:Ruby and XMPP/Jabber - a Multi Posts Series, Part 1 blogmarks:Ruby and XMPP/Jabber - a Multi Posts Series, Part 1 Y!:Ruby and XMPP/Jabber - a Multi Posts Series, Part 1 smarking:Ruby and XMPP/Jabber - a Multi Posts Series, Part 1 magnolia:Ruby and XMPP/Jabber - a Multi Posts Series, Part 1 segnalo:Ruby and XMPP/Jabber - a Multi Posts Series, Part 1

Deploying to Staging and Production with Capistrano

Posted by Guy Naor Thu, 28 Sep 2006 17:07:30 GMT

After an application is released, deployment should be in stages. To a test server, a staging server and a production one. I hope you have a staging server...

But capistrano has no knowledge of the difference between a staging and a production server. To make it easy to deploy using capistrano, a small change is needed to deploy.rb.

We add an if statement based off of an environment variable, and with it select the servers to deploy to. I also use this same variable to protect my production servers from accidental data changes, by adding an if to all data altering recipies I use only in staging (like reloading the DB and such). This way there's no way to run those commands on the production server.

Now, to deploy on staging: env DEPLOY='STAGING' cap deploy

And on production: env DEPLOY='PRODUCTION' cap deploy

Here's a small snippet of code with the change:

if ENV['DEPLOY'] == 'PRODUCTION'
   puts "*** Deploying to the \033[1;41m  PRODUCTION  \033[0m servers!"
   role :web, "www.your.domain.com"
   role :app, "app.your.domain.com
   role :db,  "db.your.domain.com", :primary => true
else
   puts "*** Deploying to the \033[1;42m  STAGING  \033[0m server!"
   role :web, "www.staging.domain.com"
   role :app, "app.staging.domain.com
   role :db,  "db.staging.domain.com", :primary => true
end

Posted in  | 4 comments | no trackbacks

del.icio.us:Deploying to Staging and Production with Capistrano digg:Deploying to Staging and Production with Capistrano spurl:Deploying to Staging and Production with Capistrano wists:Deploying to Staging and Production with Capistrano simpy:Deploying to Staging and Production with Capistrano newsvine:Deploying to Staging and Production with Capistrano blinklist:Deploying to Staging and Production with Capistrano furl:Deploying to Staging and Production with Capistrano reddit:Deploying to Staging and Production with Capistrano fark:Deploying to Staging and Production with Capistrano blogmarks:Deploying to Staging and Production with Capistrano Y!:Deploying to Staging and Production with Capistrano smarking:Deploying to Staging and Production with Capistrano magnolia:Deploying to Staging and Production with Capistrano segnalo:Deploying to Staging and Production with Capistrano

Improving the Rails Logger

Posted by Guy Naor Fri, 22 Sep 2006 20:02:00 GMT

The rails logger is VERY useful. It amazes me that I don't really feel I need a debugger in rails (after using one for years in Visual C++) and a lot of it is the console and the logger.

One thing missing from the logger, is the process id of the rails instance that is logging. This is important when you have more than one instance of your app serving requests through fcgi or mongrel or whatever. It's needed in order to enable us to see how the request was handled, as we can extract only logs that pertain to this specific request, even when it's mixed with other requests.

Using the fact that all classes in Ruby are open, we modify the logger to do what we need. Either create a file in your lib directory, or anywhere else you prefer, and in your config/environment.rb add the line:

require 'pid_logger'

The file should include the following (most of it extracted from the default rails logger):

class Logger
  private
    # Ruby 1.8.3 transposed the msg and progname arguments to format_message.
    # We can't test RUBY_VERSION because some distributions don't keep Ruby
    # and its standard library in sync, leading to installations of Ruby 1.8.2
    # with Logger from 1.8.3 and vice versa.
    if method_defined?(:formatter=)
      log_str = ""
      def format_message(severity, timestamp, progname, msg)
        log_str = "[#{$$}][#{severity[0...1]}] msg\n" # This is the only real change... Added a pid
      end
    else
      def format_message(severity, timestamp, msg, progname)
        log_str = "[#{$$}][#{severity[0...1]}] msg\n" # This is the only real change... Added a pid
      end
    end
  end

One more possible change that I use in some applications, is to color the background of debug messages I sent to the logger. The change here is also very slight. Here is the same file, but with the added coloring of the output with a green or red background depending on severity, when a line start with 4 or more > + - = characters (e.g: ">>>>>>>> This is a test" will have the >>>>>>>> part with a red backround if error, and green otherwize). It makes finding the log messages very eash.

class Logger
  private
    # Ruby 1.8.3 transposed the msg and progname arguments to format_message.
    # We can't test RUBY_VERSION because some distributions don't keep Ruby
    # and its standard library in sync, leading to installations of Ruby 1.8.2
    # with Logger from 1.8.3 and vice versa.
    if method_defined?(:formatter=)
      log_str = ""
      def format_message(severity, timestamp, progname, msg)
        log_str = "[#{$$}][#{severity[0...1]}] #{color_special_msg(msg, severity)}\n" # This is the only real change... Added a pid
      end
    else
      def format_message(severity, timestamp, msg, progname)
        log_str = "[#{$$}][#{severity[0...1]}] #{color_special_msg(msg, severity)}\n" # This is the only real change... Added a pid
      end
    end

    def color_special_msg msg, severity  
      # A small trick to get highlighting of the messages if they are our logged messages
      # that start with a long sequence of >>> or *****
      sub_color = severity[0...1] == 'E' ? '41' : '42' # Red for errors, green otherwize
      msg.sub(/^((\*|>|\+|-|=){4,})/, "\033[1;#{sub_color}m\\1\033[0m")     
    end

end

And as you can see, adding whatever changes you want to the logger is easy. So go ahead and make it work the way YOU want it to.

Posted in ,  | no comments | no trackbacks

del.icio.us:Improving the Rails Logger digg:Improving the Rails Logger spurl:Improving the Rails Logger wists:Improving the Rails Logger simpy:Improving the Rails Logger newsvine:Improving the Rails Logger blinklist:Improving the Rails Logger furl:Improving the Rails Logger reddit:Improving the Rails Logger fark:Improving the Rails Logger blogmarks:Improving the Rails Logger Y!:Improving the Rails Logger smarking:Improving the Rails Logger magnolia:Improving the Rails Logger segnalo:Improving the Rails Logger

To AJAX Or Not To AJAX That Is The Question

Posted by Guy Naor Fri, 15 Sep 2006 02:45:05 GMT

I'm sure this would have been Hamlet's question has he been with us today working as a web developer.

This subject was beaten to death already, but just a few days ago I was presented with just that decision, and it made it really clear in my mind. In my case the decision was simple, but I know it's not always the case. So having reference points might help others.

While developing the help system for Famundo that I mentioned yesterday, the admin part was developed with Ajax Scaffold and is very very nice and useable. When I did the public face of the help system, I continued with a full Ajax solution. The table of content, the internal linking and the tagging mechanism, all updated the main view using Ajax.

It was cool, it was nice, but it was a disaster as far as useability goes. You can't go forward and backward betweeb pages you've read and it makes navigation a nightmare for the user. It took me a few minutes of really trying to use it to figure this part really doesn't work well with Ajax. So instead of that I made everything into regular links, added VERY aggressive caching and it's much better now. The only thing I left with Ajax is the search which makes sense to do this way.

My conclusion from that is that if navigation is a central part of the functionality - don't do Ajax. Just use standard and expected navigation. It's more intutive and easier to use.

For editng/updating heavy interfaces, Ajax makes a lot of sense.

Posted in  | no comments | no trackbacks

del.icio.us:To AJAX Or Not To AJAX That Is The Question digg:To AJAX Or Not To AJAX That Is The Question spurl:To AJAX Or Not To AJAX That Is The Question wists:To AJAX Or Not To AJAX That Is The Question simpy:To AJAX Or Not To AJAX That Is The Question newsvine:To AJAX Or Not To AJAX That Is The Question blinklist:To AJAX Or Not To AJAX That Is The Question furl:To AJAX Or Not To AJAX That Is The Question reddit:To AJAX Or Not To AJAX That Is The Question fark:To AJAX Or Not To AJAX That Is The Question blogmarks:To AJAX Or Not To AJAX That Is The Question Y!:To AJAX Or Not To AJAX That Is The Question smarking:To AJAX Or Not To AJAX That Is The Question magnolia:To AJAX Or Not To AJAX That Is The Question segnalo:To AJAX Or Not To AJAX That Is The Question

Ajax and Caching

Posted by Guy Naor Tue, 12 Sep 2006 17:30:18 GMT

Sorry I didn't write for so long... Too busy working, I guess.

I wrote a tiny help system for Famundo. It's like a VERY oppinionated CMS ;-).

It's wiki like for entering the help pages, and uses caching for serving out the pages to the users. I'll have more details about, and if anyone is interested, we have plans for open sourcing it.

I was using some Ajax to display the pages, but then discovered that Ajax and caching are not too friendly to each other.

Caching in rails works only for GET out of the box, and Ajax calls are POST by default. So I changed that to POST using :method => :get in link_to_remote.

But this brings a new problem - any AJAX call that uses RJS templates, or the

render :update do |page|

end

methods will fail with page caching, as the Ajax caller expects the returned content to be of type text/javascript, but after being cached to a page, the content type returned by the server will be text/html, and the Ajax listener won't handle it correctly.

The option we have for handling this is either to find a way for the webserver server to serve different file (and we will have to save the files with the correct extension), or use fragment caching.

It works perfectly with fragments, but then caching isn't as aggressive, because for every call the rails process still needs to be called.

Posted in ,  | no comments | no trackbacks

del.icio.us:Ajax and Caching digg:Ajax and Caching spurl:Ajax and Caching wists:Ajax and Caching simpy:Ajax and Caching newsvine:Ajax and Caching blinklist:Ajax and Caching furl:Ajax and Caching reddit:Ajax and Caching fark:Ajax and Caching blogmarks:Ajax and Caching Y!:Ajax and Caching smarking:Ajax and Caching magnolia:Ajax and Caching segnalo:Ajax and Caching

Say Hello To A New Typo Version

Posted by Guy Naor Fri, 07 Jul 2006 01:05:16 GMT

Just a short note that I switched the blog to a more recent version of Typo (2.6 with more recent changes included).

This change also includes a new Famundo theme, so the blog match the rest of our sites. It also let me published syntax highlighted code in a much nicer format.

More development related posts are in the way, ejoy the new look for now...

2 comments | no trackbacks

del.icio.us:Say Hello To A New Typo Version digg:Say Hello To A New Typo Version spurl:Say Hello To A New Typo Version wists:Say Hello To A New Typo Version simpy:Say Hello To A New Typo Version newsvine:Say Hello To A New Typo Version blinklist:Say Hello To A New Typo Version furl:Say Hello To A New Typo Version reddit:Say Hello To A New Typo Version fark:Say Hello To A New Typo Version blogmarks:Say Hello To A New Typo Version Y!:Say Hello To A New Typo Version smarking:Say Hello To A New Typo Version magnolia:Say Hello To A New Typo Version segnalo:Say Hello To A New Typo Version

Rotating the Rails logs with FastCGI

Posted by Guy Naor Fri, 23 Jun 2006 15:47:00 GMT

Deploying a rails app will eventually lead to the need to manage the rails log files. They get pretty big fast, and if the log level also include the SQL queries, they grow EXTREMLY fast.

Though there is some information about it in the Rails Wiki, it's missing restarting the FastCGI processes. If you are using dynamicaly launched FastCGI processes from lighty or apache, the web server log rotation will restart the FastCGI processes and you will be covered. But if you are using FastCGI processes you launch (using spinner/spawner or a similar solution) the log file will be rotated, but the newly created log file won't be used by the ruby app until it is restarted.

Here is my logrotate configuration:

# Assume the the rails app is installed to /app/my_blog/current
# And that the user we running the app with is called rails
/app/my_blog/current/log/*.log {
  daily
  missingok
  rotate 7
  compress
  delaycompress
  notifempty
  create 0660 rails rails
  postrotate
     /app/my_blog/current/script/process/reaper -a graceful -d /app/my_blog/current/public/dispatch.fcgi 1>/dev/null 2>&1 || true
  endscript
}

The main change from the rails wiki version is the postrotate call that causes the fastCGI processes to restart and reopen the log file.

Posted in , ,  | no comments | no trackbacks

del.icio.us:Rotating the Rails logs with FastCGI digg:Rotating the Rails logs with FastCGI spurl:Rotating the Rails logs with FastCGI wists:Rotating the Rails logs with FastCGI simpy:Rotating the Rails logs with FastCGI newsvine:Rotating the Rails logs with FastCGI blinklist:Rotating the Rails logs with FastCGI furl:Rotating the Rails logs with FastCGI reddit:Rotating the Rails logs with FastCGI fark:Rotating the Rails logs with FastCGI blogmarks:Rotating the Rails logs with FastCGI Y!:Rotating the Rails logs with FastCGI smarking:Rotating the Rails logs with FastCGI magnolia:Rotating the Rails logs with FastCGI segnalo:Rotating the Rails logs with FastCGI

Finding Good Color Contrast

Posted by Guy Naor Wed, 14 Jun 2006 14:20:00 GMT

Giving our Famundo users the ability to change some background colors on the header to match the logo, brough up the problem of selecting the correct color to use for text we have to write on the header. We can't default to just a specific color as it might not be readable on some of the colors.

The W3C recommends how to select colors to achieve good readability. It's a nice formula to find the color contrast and brightness difference. They also recommend on a treshold to compare against, when selecting the colors. I wrote ruby code to do that calculation. You can change the tresholds to give you more latitute in selecting colors.

# Return true if the difference between two colors 
# matches the W3C recommendations for readability
# See http://www.wat-c.org/tools/CCA/1.1/
def colors_diff_ok? c1, c2
  cont, bright = find_color_diff c1, c2
  (cont > 500) && (bright > 125) # Acceptable diff according to w3c
end

# Return the contranst and brightness difference between two RGB values
def find_color_diff c1, c2
  r1, g1, b1 = break_color c1
  r2, g2, b2 = break_color c2
  cont_diff = (r1-r2).abs+(g1-g2).abs+(b1-b2).abs # Color contrast
  bright1 = (r1 * 299 + g1 * 587 + b1 * 114) / 1000
  bright2 = (r2 * 299 + g2 * 587 + b2 * 114) / 1000
  brt_diff = (bright1 - bright2).abs # Color brightness diff
  [cont_diff, brt_diff]
end

# Break a color into the R, G and B components    
def break_color rgb
  r = (rgb & 0xff0000) >> 16
  g = (rgb & 0x00ff00) >> 8
  b = rgb & 0x0000ff
  [r,g,b] 
end

A simple way to use it, is to have an array with different color options, and look in it for a match:

possible_colors = [0xff0000, 0x00ff00, 0x0000ff, 0xffff00, 0x00ffff, 0xffffff]
good_color = 0 # We can default to black...
possible_colors.each do |c|
  if colors_diff_ok? c, my_color
    good_color = c
    break
  end
end

Posted in  | no comments | no trackbacks

del.icio.us:Finding Good Color Contrast digg:Finding Good Color Contrast spurl:Finding Good Color Contrast wists:Finding Good Color Contrast simpy:Finding Good Color Contrast newsvine:Finding Good Color Contrast blinklist:Finding Good Color Contrast furl:Finding Good Color Contrast reddit:Finding Good Color Contrast fark:Finding Good Color Contrast blogmarks:Finding Good Color Contrast Y!:Finding Good Color Contrast smarking:Finding Good Color Contrast magnolia:Finding Good Color Contrast segnalo:Finding Good Color Contrast

Fixing Rails for Postgres Schemas

Posted by Guy Naor Sat, 03 Jun 2006 22:26:00 GMT

Postgres has a very powerful feature in the schemas, especially with the schema search_path. Using it I can have multiple separate families, all using the same database connection, but also fully separated (with a different user to access the schema files). Using the search path and the SESSION AUTHORIZATION it is completely transparent to rails. I'll have a later post explaining how to use this technique in a rails application.

The cool thing about the search_path is that you can have multiple instances of the same table in different schemas, and using SET SESSION AUTHORIZATION, you can see a different table each time. Rails works great with this.

But there's a small bug in the postgres driver for handling sequences. (The bug doesn't show up in development mode because the objects are reloaded all the time.) When postgres loads the sequence name used for the auto increment keys (serial type in postgres), it adds the schema to the sequence name. So instead of messages_id_seq, it will return public.messages_id_seq. If another request coming in, tries to insert a record, the call to SELECT currval() will return the wrong sequence, and if (like I do) there's user security between schemas, you get an access error and the insert fails.

The fix is very simple - just return the unqualified sequence name, as the rest of the access in rails is unqualified.

I'm posting a ticket with the fix and a test file for it. The fix to the rails edge is the following (in diff format):

Index: lib/active_record/connection_adapters/postgresql_adapter.rb
===================================================================
--- lib/active_record/connection_adapters/postgresql_adapter.rb (revision 4414)
+++ lib/active_record/connection_adapters/postgresql_adapter.rb (working copy)
@@ -296,8 +296,9 @@
               AND def.adsrc ~* 'nextval'
           end_sql
         end
-        # check for existence of . in sequence name as in public.foo_sequence.  if it does not exist, join the current namespace
-        result.last['.'] ? [result.first, result.last] : [result.first, "#{result[1]}.#{result[2]}"]
+        # check for existence of . in sequence name as in public.foo_sequence.  if it does not exist, return unqualified sequence
+        # We cannot qualify unqualified sequences, as rails doesn't qualify any table access, using the search path
+        [result.first, result.last]
       rescue
         nil
       end
                                                                                                                                

Posted in ,  | no comments | no trackbacks

del.icio.us:Fixing Rails for Postgres Schemas digg:Fixing Rails for Postgres Schemas spurl:Fixing Rails for Postgres Schemas wists:Fixing Rails for Postgres Schemas simpy:Fixing Rails for Postgres Schemas newsvine:Fixing Rails for Postgres Schemas blinklist:Fixing Rails for Postgres Schemas furl:Fixing Rails for Postgres Schemas reddit:Fixing Rails for Postgres Schemas fark:Fixing Rails for Postgres Schemas blogmarks:Fixing Rails for Postgres Schemas Y!:Fixing Rails for Postgres Schemas smarking:Fixing Rails for Postgres Schemas magnolia:Fixing Rails for Postgres Schemas segnalo:Fixing Rails for Postgres Schemas

Older posts: 1 2 3 4 5 6

Subscribe to The Dev Blog