How to add sequences to a migration and use them in a model?

rails-migrations, rails-models, rails-postgresql, ruby-on-rails, ruby-on-rails-3.1

Solution

I have no suggestions for a more 'rails way' of handling custom sequences, but I can tell you why the customer_no field appears not to be being populated after a save.

When ActiveRecord saves a new record, the SQL statement will only return the ID of the new record, not all of its fields, you can see where this happens in the current rails source here https://github.com/rails/rails/blob/cf013a62686b5156336d57d57cb12e9e17b5d462/activerecord/lib/active_record/persistence.rb#L313

In order to see the value you will need to reload the object...

cust = Accounts::Customer.new
cust.save
cust.reload

If you always want to do this, consider adding an after_create hook in to your model class...

class Accounts::Customer < ActiveRecord::Base
  after_create :reload
end

Problem

I want to have a "`Customer`" Model with a normal primary key and another column to store a custom "Customer Number". In addition, I want the db to handle default Customer Numbers. I think, defining a sequence is the best way to do that. I use PostgreSQL. Have a look at my migration: ``` class CreateAccountsCustomers < ActiveRecord::Migration def up say "Creating sequenze for customer number starting at 1002" execute 'CREATE SEQUENCE customer_no_seq START 1002;' create_table :accounts_customers do |t| t.string :type t.integer :customer_no, :unique => true t.integer :salutation, :limit => 1 t.string :cp_name_1 t.string :cp_name_2 t.string :cp_name_3 t.string :cp_name_4 t.string :name_first, :limit => 55 t.string :name_last, :limit => 55 t.timestamps end say "Adding NEXTVAL('customer_no_seq') to column cust_id" execute "ALTER TABLE accounts_customers ALTER COLUMN customer_no SET DEFAULT NEXTVAL('customer_no_seq');" end def down drop_table :accounts_customers execute 'DROP SEQUENCE IF EXISTS customer_no_seq;' end end ``` If you know a better "rails-like" approach to add sequences, would be awesome to let me know. Now, if I do something like ``` cust = Accounts::Customer.new cust.save ``` the field `customer_no` is not pre filled with the next value of the sequence (should be 1002). Do you know a good way to integrate sequences? Or is there a good plugin? Cheers to all answers!

Original source

Related problems