Wednesday, November 24, 2010

Rails TypeError (can't convert String into Integer) on save


RoR is fun !

Unless... you encounter some problem that google cannot explain ;)

So recently I've got some strange TypeError (can't convert String into Integer) in .rvm/gems/ruby-1.9.2-p0/gems/activerecord-3.0.3/lib/active_record/connection_adapters/abstract/database_statements.rb:319 when doing .save on my object.

Records were successfully saved into database but this error stopped app from execution.
I've investigated this a little, trying to find this mysterious String which ruby wants to convert to Integer.
Let me tell you a little about my object I want to save.
    class CreateSites < ActiveRecord::Migration
      def self.up
        create_table :sites do |t|
          t.integer :id, :null => false
          t.text :title, :null => false
          t.column :hash, :'varchar(32)', :null => false
          t.text :description, :null => false
          t.column :user_id, 'integer references users(id)', :null => false
          t.timestamps
        end
      end

      def self.down
        drop_table :sites
      end
    end

This is my migration file, clean and simple. Nothing can be wrong here, well that's a lie ;)

Ruby was complaining about my hash field, why ? Because every object in ruby has a hash method, which is used for eg. in comparison when doing Array.uniq (which is done in rails). Then when I created this migration, rails created a Class which was overwriting hash method (which returns int) to return the db value (which is string).
Sooooooo not cool ! Why this isn't documented anywhere ? Shame on you rails developers ! It should be red in migration guide - DO NOT USE "HASH" AS A FIELD NAME, IT WILL BREAK YOUR APP

Wednesday, November 17, 2010

Rails 3 + Foreign Key

Hi there !

Recently I've been doing some railing on rails 3. They're pretty cool actually but you can read about it elsewhere ;)

Though, there is this "foreign key" problem. Rails != Hibernate so sometimes we must work some magic.
We cannot do native foreign keys so we'll do it the "hard way" (which is btw very easy)
I'm using PostgreSQL (if you aren't - you should !) This method will probably won't work for other databases but I don't care, so...
We take our migration file and put there :
t.column :site_id, 'integer references sites(id)', :null => false
t.column :user_id, 'integer references users(id)', :null => false
t.column :parent, 'integer references comments(id)'
or something similar.
And that's it ! We don't need any plugins. Foreign keys are created.
Foreign-key constraints:
    "comments_parent_fkey" FOREIGN KEY (parent) REFERENCES comments(id)
    "comments_site_id_fkey" FOREIGN KEY (site_id) REFERENCES sites(id)
    "comments_user_id_fkey" FOREIGN KEY (user_id) REFERENCES users(id)
Referenced by:
    TABLE "comments" CONSTRAINT "comments_parent_fkey" FOREIGN KEY (parent) REFERENCES comments(id)
That's so awesome, isn't it ?

Sunday, November 7, 2010

How to cheat in iStudent facebook competition

Well on facebook, there is this iStudent competition. If you win apple will give you some gadgets so you can show off in college. Sounds fun, right ?
To participate you need to register and use iStudent facebook app. There you'll get some question that you need to answer. Tricky part is that there's limited time for that, each couple of seconds you loose one point. So... what can you do to stop the time ? It's easy, buy a time machine ! No, but really, just install NoScript for firefox and you're good. Seriously. You can always create second facebook account to get the questions and cheat, but this is just sooooo easy ! Anyway, have fun. You can get also points for inviting friends but that's just too easy. I hope I'll write here more often than once a year ;)

Cheers !

BTW.
Remember, fact that you can cheat do not allow you to do so ! ;-)