Lighthouse has a new layout. Prefer the old one? Return to the old layout, and switch back any time from the link at the top of each page.

This project is archived and is in readonly mode.

rails does not handle columns that start with a number

#3984

I have a database that I want to create a rails frontend for, and am attempting with rails 3.0.0beta. One of the tables has a column named 2_3. rails tries to create method accessors, and ruby wants them to be starting with [a-z_].

irb(main):001:0> Task.find(1)
=> #<Task id: 1, user: "cwevans", tid: 11464, comment: "", created_at: "2010-02-15 07:57:02", updated_at: "2010-02-15 07:57:02">
irb(main):002:0> Task.find(1).em7_ticket
=> #<Em7Ticket tid: 11464, Xid: 25135, Xtype: 0, Xname: "", aid: 0, roa_id: 25006, roa_lid: 0, class: 15, descr: "Duplicate VIP recap", severity: 4, status: 0, source: 45, date_create: "2010-01-26 15:26:01", user_create: "system", date_update: "2010-02-09 16:44:01", user_update: "system", assign: 34, assigned_to: "cwevans", resolution: 0, cause: 0, escalation: 2, hours_billed: 0.0, user_close: "", date_close: nil, close_age: "", auto_close: 0, master_tid: 0, 2_1: "- No Project -">
irb(main):003:0> Task.find(1).em7_ticket.task
SyntaxError: compile error
/usr/local/lib/ruby/gems/1.8/gems/activemodel-3.0.0.beta/lib/active_model/attribute_methods.rb:258: syntax error, unexpected tINTEGER
                 def 2_1?(*args)
                        ^
/usr/local/lib/ruby/gems/1.8/gems/activemodel-3.0.0.beta/lib/active_model/attribute_methods.rb:258: syntax error, unexpected ')', expecting '='
/usr/local/lib/ruby/gems/1.8/gems/activemodel-3.0.0.beta/lib/active_model/attribute_methods.rb:260: syntax error, unexpected kEND, expecting ')'
   from /usr/local/lib/ruby/gems/1.8/gems/activemodel-3.0.0.beta/lib/active_model/attribute_methods.rb:260:in `define_attribute_methods'
   from /usr/local/lib/ruby/gems/1.8/gems/activemodel-3.0.0.beta/lib/active_model/attribute_methods.rb:250:in `each'
   from /usr/local/lib/ruby/gems/1.8/gems/activemodel-3.0.0.beta/lib/active_model/attribute_methods.rb:250:in `define_attribute_methods'
   from /usr/local/lib/ruby/gems/1.8/gems/activemodel-3.0.0.beta/lib/active_model/attribute_methods.rb:249:in `each'
   from /usr/local/lib/ruby/gems/1.8/gems/activemodel-3.0.0.beta/lib/active_model/attribute_methods.rb:249:in `define_attribute_methods'
   from /usr/local/lib/ruby/gems/1.8/gems/activerecord-3.0.0.beta/lib/active_record/attribute_methods.rb:12:in `define_attribute_methods'
   from /usr/local/lib/ruby/gems/1.8/gems/activerecord-3.0.0.beta/lib/active_record/attribute_methods.rb:41:in `respond_to?'
   from /usr/local/lib/ruby/g

To test a similar case, I used rails 2.3.5

rails generate scaffold task 2_3:string
./script/generate scaffold task 2_3:string
[root@hold-dev-app01 attribute_number]# rake --trace db:migrate
(in /root/attribute_number)
 Invoke db:migrate (first_time)
 Invoke environment (first_time)
 Execute environment
 Execute db:migrate
rake aborted!
./db/migrate//20100217201534_create_tasks.rb:4: syntax error, unexpected tINTEGER, expecting tSTRING_CONTENT or tSTRING_DBEG or tSTRING_DVAR or tSTRING_END
/usr/local/lib/ruby/gems/1.8/gems/activesupport-2.3.5/lib/active_support/dependencies.rb:145:in load_without_new_constant_marking'
/usr/local/lib/ruby/gems/1.8/gems/activesupport-2.3.5/lib/active_support/dependencies.rb:145:inload'
/usr/local/lib/ruby/gems/1.8/gems/activesupport-2.3.5/lib/active_support/dependencies.rb:521:in new_constants_in'
/usr/local/lib/ruby/gems/1.8/gems/activesupport-2.3.5/lib/active_support/dependencies.rb:145:inload'
/usr/local/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/migration.rb:373:in load_migration'
/usr/local/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/migration.rb:369:inmigration'
/usr/local/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/migration.rb:365:in migrate'
/usr/local/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/migration.rb:486
/usr/local/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/migration.rb:560:incall'
/usr/local/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/migration.rb:560:in ddl_transaction'
/usr/local/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/connection_adapters/abstract/database_statements.rb:136:intransaction'
/usr/local/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/transactions.rb:182:in transaction'
/usr/local/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/migration.rb:560:inddl_transaction'
/usr/local/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/migration.rb:485:in migrate'
/usr/local/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/migration.rb:472:ineach'
/usr/local/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/migration.rb:472:in migrate'
/usr/local/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/migration.rb:400:inup'
/usr/local/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/migration.rb:383:in migrate'
/usr/local/lib/ruby/gems/1.8/gems/rails-2.3.5/lib/tasks/databases.rake:116
/usr/local/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:636:incall'
/usr/local/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:636:in execute'
/usr/local/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:631:ineach'
/usr/local/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:631:in execute'
/usr/local/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:597:ininvoke_with_call_chain'
/usr/local/lib/ruby/1.8/monitor.rb:242:in synchronize'
/usr/local/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:590:ininvoke_with_call_chain'
/usr/local/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:583:in invoke'
/usr/local/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:2051:ininvoke_task'
/usr/local/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:2029:in top_level'
/usr/local/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:2029:ineach'
/usr/local/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:2029:in top_level'
/usr/local/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:2068:instandard_exception_handling'
/usr/local/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:2023:in top_level'
/usr/local/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:2001:inrun'
/usr/local/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:2068:in standard_exception_handling'
/usr/local/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:1998:inrun'
/usr/local/lib/ruby/gems/1.8/gems/rake-0.8.7/bin/rake:31
/usr/local/bin/rake:19:in load'
/usr/local/bin/rake:19</code>
</pre>

Reported by Christopher Evans · February 17th, 2010 @ 08:37 PM

State: stale
Milestone: none
Assigned to: nobody
Importance: Low

Activity

  1. Elad Meidar
    Elad Meidar

    I don't really think it makes any sense.

    Since columns are accessed via getter/setter ruby methods, the Ruby language restriction of not using method names that start with a number is a blocker for this fix.

    Not sure if there's a workaround/hack to solve this somehow, but it doesn't make too much sense to name a method that begins with a number either... simply replace the method name digits with explicit description:

    def two_one?
    

    June 18th, 2010 @ 11:07 AM

  2. Rohit Arondekar
    Rohit Arondekar
    • State changed from new to wontfix

    June 18th, 2010 @ 11:08 AM

  3. Christopher Evans
    Christopher Evans

    Sorry, I didn't describe the issue in the best terms.

    The issue is that the database table has columns that start with numbers.

    mysql> describe asset_dynamic_embed;
    +-------+------------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+------------------+------+-----+---------+-------+ | id | int(11) unsigned | NO | MUL | 0 | | | 1_2 | varchar(32) | NO | | | | | 6_2 | varchar(32) | NO | | | | | 7_2 | varchar(32) | NO | | | | | 8_2 | varchar(32) | NO | | | | | 9_2 | varchar(32) | NO | | | | | 10_2 | varchar(48) | NO | | | | | 11_2 | varchar(32) | NO | | | | | 12_2 | varchar(32) | NO | | | | | 13_2 | varchar(32) | NO | | | | | 14_2 | varchar(32) | NO | | | | | 15_2 | varchar(32) | NO | | | | | 16_2 | varchar(32) | NO | | | | | 17_2 | varchar(32) | NO | | | | | 18_2 | varchar(32) | NO | | | | | 19_2 | varchar(48) | NO | | | | | 20_2 | varchar(32) | NO | | | | | 21_2 | varchar(32) | NO | | | | +-------+------------------+------+-----+---------+-------+ 18 rows in set (0.01 sec)

    June 18th, 2010 @ 07:22 PM

  4. Rohit Arondekar
    Rohit Arondekar

    Christopher, the best solution that I can give you is to migrate that legacy table to something Rails will support. It will be quite difficult to modify Rails to support column names starting with numbers as Elad has explained.

    June 19th, 2010 @ 05:25 AM

  5. Jeremy Kemper
    Jeremy Kemper
    • State changed from wontfix to open

    The workaround is to not generate Ruby accessors for columns with invalid Ruby names. They're still accessible using read_attribute and []. Seems reasonable.

    Christopher, got a patch + tests?

    June 19th, 2010 @ 06:56 AM

  6. Santiago Pastorino
    Santiago Pastorino
    • Importance changed from to Low

    This issue has been automatically marked as stale because it has not been commented on for at least three months.

    The resources of the Rails core team are limited, and so we are asking for your help. If you can still reproduce this error on the 3-0-stable branch or on master, please reply with all of the information you have about it and add "[state:open]" to your comment. This will reopen the ticket for review. Likewise, if you feel that this is a very important feature for Rails to include, please reply with your explanation so we can consider it.

    Thank you for all your contributions, and we hope you will understand this step to focus our efforts where they are most helpful.

    February 2nd, 2011 @ 04:37 PM

  7. Santiago Pastorino
    Santiago Pastorino
    • State changed from open to stale

    February 2nd, 2011 @ 04:37 PM

  8. bingbing