Showing posts with label databases. Show all posts
Showing posts with label databases. Show all posts

Monday, February 2, 2015

Updating a Rails Model with a Non-default Primary Key

In my last post, I talked about creating a Rails model with a non-default primary key. You can create new instances of the model with no problem, but what happens when you want to update an instance of the model?
 TypeError: nil is not a symbol nor a string  
Oh no!!!!

Fortunately, there is an easy fix. You just have to specify the column name of the primary key from within the model.
 class BearHabitat < ActiveRecord::Base  
   self.primary_key = 'bear_id'  
 end  
Now you should be able to update your model within your code with no problem. Why does this happen in the first place? My guess is that somewhere within ActiveModel, it assumes that the primary_key field is set. Since your migration set id to false, this value gets defaulted to nil. If you don't manually set it, ActiveModel gets sad. Now you can make ActiveModel happy again.

Saturday, January 31, 2015

Creating a Rails Model with a Non-default Primary Key

One of the main Rails philosophies is "convention over configuration". This works great most of the time, but sometimes it's best to do something outside of convention. One example is the primary key for models. Sometimes you want the key to be something other than ID; maybe you want it to be the ID of a related model.

This is possible to set up in a migration, you just need to do a few important things:
  • Set id: false on the create_table line
  • Set your new primary key to null: false
  • Add a unique index on your new primary key
Here is an example:

 class CreateBearHabitats < ActiveRecord::Migration  
   def change  
     create_table :bear_habitats, id: false do |t|  // prevents a default ID column from being created
       t.belongs_to :bear, null: false //creates a bear_id column that can not be null
       t.string :habitat  
     end  

     add_index :bear_habitats, :bear_id, unique: true // ensures that the bear_id column is unique
   end  
 end  
This BearHabitat model will now use bear_id as a primary key instead of the standard id.

Friday, January 16, 2015

Rake Database Tasks Outside Rails

My first content post is, ironically, not directly about Rails. It is about using a very common Rails feature - rake database tasks - in a Ruby project that utilizes ActiveRecord but not Rails.

By default, tasks like rake db:migrate are available in Rails but not in a Ruby project that includes ActiveRecord. Fortunately, with a couple of lines added to your Rakefile this issue can be fixed.
 // Rakefile
 DatabaseTasks.env = ENV['YOUR_ENV_VAR'] || 'development'  
 DatabaseTasks.db_dir = 'db'  
 DatabaseTasks.database_configuration = YAML.load_file('config/database.yml')  
 DatabaseTasks.migrations_paths = "#{DatabaseTasks.db_dir}/migrate"  
 task :environment do  
  ActiveRecord::Base.configurations = DatabaseTasks.database_configuration  
  ActiveRecord::Base.establish_connection DatabaseTasks.env.to_sym  
 end  
 load 'active_record/railties/databases.rake'  
And voila. Now, you can use create, migrate, and all of the other rake db tasks you're used to in a Rails project.