n00b here, rake error: Expected x.rb to define x

I've searched through the forum and google, and to no avail. I cannot seem to find the solution to my problem. No one has ever defined this as a rake problem. Anyway, it's when my db:migrate tries to process this migration:

class AddPaymentTypeData < ActiveRecord::Migration   def self.up     Payment_type.delete_all

    Payment_type.create(:type => 'Check')     Payment_type.create(:type => 'Credit Card')     Payment_type.create(:type => 'Purchase Order')   end

  def self.down     Payment_type.delete_all   end end

that it gives me the error: rake aborted! Expected /Users/joel/Sites/depot/app/models/payment_type.rb to define Payment_type

I have a payment_type.rb file:

class PaymentType < ActiveRecord::Base

  has_many :orders

end

This is in the right place, in the path that the rake task is complaining that it isn't. Does anyone have any idea why this is happening? I'm sure someone has run into this before. I'm using rails 2.2.2, ruby 1.8.

Thanks in advance.

Groove

Hi --

I've searched through the forum and google, and to no avail. I cannot seem to find the solution to my problem. No one has ever defined this as a rake problem. Anyway, it's when my db:migrate tries to process this migration:

class AddPaymentTypeData < ActiveRecord::Migration def self.up    Payment_type.delete_all

   Payment_type.create(:type => 'Check')    Payment_type.create(:type => 'Credit Card')    Payment_type.create(:type => 'Purchase Order') end

def self.down    Payment_type.delete_all end end

that it gives me the error: rake aborted! Expected /Users/joel/Sites/depot/app/models/payment_type.rb to define Payment_type

I have a payment_type.rb file:

class PaymentType < ActiveRecord::Base

has_many :orders

end

This is in the right place, in the path that the rake task is complaining that it isn't. Does anyone have any idea why this is happening? I'm sure someone has run into this before. I'm using rails 2.2.2, ruby 1.8.

The short answer is: change Payment_type to PaymentType in your create statments (and everywhere else).

Longer answer:

Rails has a "magic" way of resolving references to unknown constants. If you refer, say, to PaymentType, without having defined it, Rails does the following:

   1. convert "PaymentType" to its canonical "underscore" equivalent,      "payment_type"    2. add ".rb" to the end    3. search the file load-path for a file called that      ("payment_type.rb")    4. load the file    5. confidentally assume that PaymentType is now defined

You made it as far as 4 (it found app/models/payment_type.rb), but only by coincidence: you used "Payment_type", which also turns into "payment_type.rb". So the file was found -- but at no point inside the file did you define a constant called "Payment_type". What you really want is for Rails to be looking for the constant PaymentType, not Payment_type, and that's why you need to correct your Payment_type references to PaymentType. (And in any case, you need to use the same name for the same constant consistently :slight_smile:

David

I've searched through the forum and google, and to no avail. I cannot seem to find the solution to my problem. No one has ever defined this as a rake problem. Anyway, it's when my db:migrate tries to process this migration:

class AddPaymentTypeData < ActiveRecord::Migration def self.up    Payment_type.delete_all

That should be PaymentType

Fred

Hi --

I've searched through the forum and google, and to no avail. I cannot seem to find the solution to my problem. No one has ever defined this as a rake problem. Anyway, it's when my db:migrate tries to process this migration:

In addition to David's answer below, let me add two cautions:

1. Whenever you're using the model inside a migration, it is a good idea to define a minimal copy of the model actually within the migration. This guards against future changes to the model class (including the model going away!).

  1.a. If you ever use the model to manipulate data after changing the underlying table (e.g., add_column), you need to call Model.reset_column_information so ActiveRecord takes a fresh look at the database columns.

2. Having a column named "type" in ActiveRecord signifies the actual class name when using Single-Table Inheritance (STI). If you get errors later because it can't find a class called "Check", remember this (and pick a different name; it's easier than struggling with ActiveRecord).

-Rob

Rob Biedenharn http://agileconsultingllc.com Rob@AgileConsultingLLC.com

class AddPaymentTypeData < ActiveRecord::Migration

     class PaymentType < ActiveRecord::Base; end

That did it!

@David, changed Payment_type to PaymentType in my migration file so it now looks like:

class AddPaymentTypeData < ActiveRecord::Migration   def self.up     PaymentType.delete_all

    PaymentType.create(:payment_type => 'Check')     PaymentType.create(:payment_type => 'Credit Card')     PaymentType.create(:payment_type => 'Purchase Order')   end

  def self.down     PaymentType.delete_all   end end

@Rob also, changed (obviously) the "type" column to "payment_type".

This may be a superfluous question, but does that mean the the actual object defined by the payment_type.rb file will ALWAYS be called PaymentType?

Thank you for all of your help.

Groove

That did it!

@David, changed Payment_type to PaymentType in my migration file so it now looks like:

class AddPaymentTypeData < ActiveRecord::Migration def self.up    PaymentType.delete_all

   PaymentType.create(:payment_type => 'Check')    PaymentType.create(:payment_type => 'Credit Card')    PaymentType.create(:payment_type => 'Purchase Order') end

def self.down    PaymentType.delete_all end end

@Rob also, changed (obviously) the "type" column to "payment_type".

This may be a superfluous question, but does that mean the the actual object defined by the payment_type.rb file will ALWAYS be called PaymentType?

You probably could have made the change to "class Payment_type" in the
model file, too, but the naming conventions expect that the model
class is in CamelCase and the file is in under_score.rb (ok,
camel_case.rb, but you get the idea).

-Rob