Tilo asked:

Using id instead of oid / ActiveRecord backwards-compatiblity

I need to stay backwards-compatible to ActiveRecord..

How can I use 'id' instead of 'oid' in MySQL Tables created by Og?

What other gotcha's do I need to be aware of?

thanks

T.

(2 attempts)

Tilo answered:

Thank you Kashia for your reply!

I dug into the source code and played around with this...

when I used the following line for defining the primary key, it would work only half-way.. The column would get created, but the id would not be set automatically and it would not be auto-incremented:

property :id, Integer, :primary_key => true      # does not work completely

To make it fully work and automatically increment the id, I needed to do this:

either:

property :id, Integer, :sql => "NOT NULL AUTO_INCREMENT PRIMARY KEY"
or:
property :id, Integer, :primary_key => true, :sql => "NOT NULL AUTO_INCREMENT"

either one of the above lines will work, and when an object is saved as a table-entry, then the id is automatically added and auto-incremented - just as one would expect.. :-)

So that'll do the trick, but it's really ugly to have to resort to SQL ... ;-)

I also found one more gotcha re. ActiveRecord Compatibility:

I ran into some problems setting the table prefix in the configuration options. I noticed that this does not get rid of the table prefix:

mysql_config = {
 ...

  :table_prefix => ''    # this does NOT work!
}

Instead, I had to do either:

Og.table_prefix = ''  # do this outside the options definition, before you do 'Og.connect'

  ...

  my_db = Og.connect(mysql_config)

or in the Class definition, one can also do the following to set an arbitrary table name, e.g. a plural name as in ActiceRecord, and one can also define the primary key like this:

class Example
  ...
  
  self.set_primary_key(:id)    # doing this instead of :primary_key => true also works

  self.set_table('examples')   # set the table name to some fixed string (e.g. plural form)

end

The above should also work without the 'self.'

Suggestions for Improvement:

1) it would be really cool, if the table prefix and the default primary key name would be taken from the connection options, which are given to the og.connect call, and if perhaps the pluralization of table names would be an option, e.g.:

# it would be cool if this would work:
# ====================================

mysql_config = {
   
     ...

     :default_id => 'id',  # use 'id' instead of 'oid' in all tables for this connection, 
                           # and set and auto-increment id correctly..
     :table_prefix => '',    # this should work in the configuration options!

     :pluralize_tables => true   # would be cool to have this option,
                                 # to name tables like ActiveRecord does
}

E.g. where :oid is defined in the library code, just make it a variable which has a default value, which can be over-ridden by the :defaultid declaration. Same for tableprefix.

If the above could be implemented, that would help a lot in making Og more universally useful outside Nitro.

e.g. I need to populate the data for a Rails application with some large amount of data from several sources, and I'm doing this with a separate stand-alone script. I would rather
do this in an OO fashion with Og, than having to use ActiveRecord for this - with Og it would be simpler to code, easier to understand and simply more beautiful..

2) Is it possible to tell Og to be careful with pre-existing ('legacy') databases? This would be really important, if someone wanted to use Og with such legacy databases..

3) the documentation for Og is rudimentary... it would be good to put a little meat around the minimalistic Rdoc documentation.. Is anybody writing a book about Nitro/Og? or is it still too much in flux?

Rating: 5

Kashia answered:

As .oid is hardcoded, you have to change the primary key in every model (unless you use a common parent class/module which changes the pk). Here's how you change the primary key Og uses:

class MyModel
  attr_accessor :id, Fixnum, :primary_key => true
end

# Or

class MyModel2
  attr_accessor :id, Fixnum
  set_primary_key :id
end

# Or (untested)

module CommonModel
  set_primary_key :id
end

class MyModel3
  include CommonModel

  attr_accessor :id, Fixnum
end

# Or (as Og creates the :oid column by default as well)

module CommonModel
  attr_accessor :id, Fixnum, :primary_key => true
end

class MyModel4
  include CommonModel

  # The rest of your columns
end

Not other gotchas should be involved, but changing the default primary key could have some unwanted side-effects, as that is not as heavily tested by the test-suite. Please report any errors you get by doing that to the mailing-list, forum, me or George directly. Thank you very much.

What you should do in your code however, is not using .oid/.id to access the primary key value, use .pk. This is just an alias to the real primary key, but always works, regardless of what the actual primary key is.

Rating: 4