tl;dr Yes, you /can/ even if Colin's advice is good (AND I agree with him!)
customer = Customer.new(other_attributes_here) {|c| c.id = user.id }
customer.save

On Jan 31, 2013, at 11:01 AM, Nishan T. wrote:

> I'm migrating the tables with existing data
> I've users table and all other tables contains the user_id column and
> now i need seperate the users into two (users & customers) tables
> So i need to migrate the new customers table with existing users records
> where the user type with customer
> 
> I need to create a customers table and set the id of users records with
> user type as customer,
> which will be easy instead of migrating many of other tables(which is
> used only by customers) by checking every record with user's user type
> and assign the new id of customers table.
> 
> My tables should looks like
> 
> users table:
> 
>    id  |    name   |   ...
>   ------------------------------
>    1  |    aaa    |  ...
>    2  |    bbb    |  ...
>    4  |    ddd    |  ...
>    6  |    fff    |  ...
> 
> customers table
> 
>    id   |    name  |  ...
>   -------------------------------
>    3  |    ccc      |  ...
>    5  |    eee      |  ...
>    7  |    ggg      |  ...
> 
> When i'm migrating users existing data, I can't assign the id of user as
> customer's primary id

Well, what you can't do is use "mass assigment" to set the id of an 
ActiveRecord model.

You can, however, set the id on a new record and it will be honored if the 
database doesn't forbid it. (For example, if that primary key value already 
existed.)

> 
> In my migration file
> 
>  def up
>    create_table(:customers) do |t|
>      t.string :name
>    end
> 
>    User.joins(:user_type).where(:user_type => {:type_name =>
> 'customer'}).find_in_batches(:batch_size => 100){ |users|
>       users.each {|user|
>              customer = Customer.new
>              customer.id = user.id
>              customer.name = user.name
>              customer.save(:validate => false)
>       }
>       }
>  end
> 
> Also tried
> 
>  Customer.create!(:id => user.id) instead of save method
> 
> And
> 
>  INSERT INTO customers(id, name) VALUES("#{user.id}", "#{user.name}")
> 
> Finally all ended with same error
> 
> Error: Called id for nil, which would mistakenly be 4 -- if you really
> wanted
> the id of nil, use object_id
> 
> Is this correct?
> 
> Is there any way to assign the primary id ?
> 
> Please anyone explain how to do this?

There's even a block form of ActiveRecord.new that passes in the newly 
initialized object.

customer = Customer.new(:name => user.name) {|c| c.id = user.id }
customer.save(:validate => false)

Since you already have a "user_type", it seems like you're at least halfway to 
being STI (Single-Table Inheritance) anyway.

Couldn't you have:

class Customer < User
end

Then you'd have a `type` attribute (column) in the users table which would hold 
the class name represented by that row of data. (which could be "User" or could 
be "Customer")

Then you can say:
  r = User.find_by_name('ccc')
and r will hold an instance of the Customer class.

-Rob

-- 
You received this message because you are subscribed to the Google Groups "Ruby 
on Rails: Talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to