Implement acts_as_threaded without a plugin 30

Posted by Bob Silva Fri, 31 Mar 2006 20:40:00 GMT

It's been awhile since I've posted so I thought I'd toss this out there. If you've used my acts_as_threaded plugin, you know its an off-shoot from the acts_as_nested set inside of AR itself. I've managed to create the same functionality without the use of a plugin using the native acts_as_nested_set feature of AR. The relevant code is below. The threading functionality has been moved to the model now, add the following code to your model and you are set.
  acts_as_nested_set :scope => :root
    
  def before_create
    # Update the child object with its parents attrs
    unless self[:parent_id].to_i.zero?
      self[:depth] = parent[:depth].to_i + 1
      self[:root_id] = parent[:root_id].to_i
    end
  end
  
  def after_create
    # Update the parent root_id with its id
    if self[:parent_id].to_i.zero?
      self[:root_id] = self[:id]
      self.save
    else
      parent.add_child self
    end
  end
  
  def parent
    @parent ||= self.class.find(self[:parent_id])
  end

Your database schema will need to have the following definition:
create_table "my_table_name", :force => true do |t|
  t.column "root_id", :integer
  t.column "parent_id", :integer
  t.column "lft", :integer
  t.column "rgt", :integer
  t.column "depth", :integer
end
The trick from this point, is that whenever you create a new thread, if it has a parent_id, then it will automatically be added as a child to that parent record. Otherwise, it will be set as a root thread. This version no longer requires that the fields have a default value of 0 relying on the fact that 'NilClass.to_i == 0'.

Hope you enjoy this, it's come in very handy for modeling structured content in some of my apps (like categories and multi-level organizations).

My Macbook Finally Arrived

Posted by Bob Silva Sun, 05 Mar 2006 09:06:00 GMT

One word, two meanings. It's HOT! and Ah crap, it is HOT!

Being my first experience with Mac, I am very pleased with it. I'm still coming up to speed with OSX and haven't had much time to play with it yet. The crowning moment came when I hooked it up to the 30" cinema. What a beautiful thing to have 6 full size browser windows visible on your desktop. Pic #1 Pic #2

I am a little disappointed in the amount of heat it generates though. I made the mistake of setting it on my lap after running for a few hours, and even though I had shorts on, it still got my attention rather quick. The little area just above the F keys gets a bit toasty as well. Since the majority of the heat comes from the battery, I am a little concerned that there may be other issues than just "Apple laptops have always run hot". But who knows? For now, I'm just wanting to finish up my current projects so I can have some time to play with it more.

More Advanced Rails Schema Generation 1

Posted by Bob Silva Sun, 05 Mar 2006 08:17:00 GMT

One of the problems I've seen with Rails as of late is that the database schemas for the unit tests get out of sync with each other. As new features get added, some db_definitions get updated and others missed. The core group is well aware of this issue and DHH left a challenge in a ticket I created to add missing table definitions from a previous changeset.


I decided I would take him up on his challenge and went to work. I printed off all the db schemas and started comparing them with each other, highlighting where they differed. This was my first indication as to the scope of this conversion.


Since the purpose of converting over to using schema.rb is to maintain one schema for all the tests, it would be helpful if all the existing definitions were at least similar to begin with. Most of the differences can be fixed without issue. Converting a varchar(3000) field to text, or a timestamp to datetime is no big deal as far as the unittests are concerned. The biggest road block is that some tables are defined using features that don't exist in AR::Schema. Features like foreign keys, arbitrary primary keys and sequences. User-defined column definitions is yet another example where AR::Schema isn't up to the job. For example, the Postgres tests use a table with geometric field types.


I had a pretty good idea how to implement everything except for sequences, so I started coding and within a few hours had the test suite working with MySQL using schema.rb. Before I dove much further into making all the adapters work with schema.rb, I decided I better get some feedback on whether these changes I was making to Rails schema generation would even be accepted into core. Unfortunately, I didn't get any feedback from the core developers.


I think the biggest issue they would raise is whether or not the SchemaDumper would be able dump these changes. The short answer is no, which coincidently, is probably the same answer my patch would get. So I scrapped my work on converting the unittests over but will consider making a plugin which adds this functionality (and much more) for more advanced schema generation/migrations. You just won't be able to dump your schema out into a schema.rb file.


Let me know if you think this would be useful and I'll put something together.