is overriding file naming conventions (for models and controllers) possible?

Hello, i have another question about overriding Rails conventions.

Is it possible to tell Rails which model/controller is defined in which file?

I have generated a model and a controller as follows:

$ rails generate model KnownIP ... ... $ rails generate controller KnownIPs ...

The problem is with the "IP" in the name: now i have a model *KnownIp* in the file *known_ip.rb* and a controller *KnownIPsController* in the file *known_i_ps_controller.rb*, which does not look consistent.

The model can be renamed without problems to KnownIP. However, if the controller file is renamed to known_ips_controller.rb it (most likely) will stop working (i tested such situation with models, but not with controllers).

Another interesting example: if a model is generated with $ rails generate model known_i_p ... then it is broken from the beginning. To make it work, it is necessary to rename its file from *known_i_p.rb* to *known_ip.rb*, and to add set_table_name 'known_i_ps' to it.

Can the correspondence between file names and model names be specified manually in such odd cases?

Alexey.

Hello, i have another question about overriding Rails conventions.

Is it possible to tell Rails which model/controller is defined in which file?

I have generated a model and a controller as follows:

$ rails generate model KnownIP ... ... $ rails generate controller KnownIPs ...

The problem is with the "IP" in the name: now i have a model *KnownIp* in the file *known_ip.rb* and a controller *KnownIPsController* in the file *known_i_ps_controller.rb*, which does not look consistent.

Something's wrong with your typing here or on the console, because your model should be "KnownIP" if you typed "$ rails generate model KnownIP". If the "p" is lower case in the model, you must have typed a lower case p...

The model can be renamed without problems to KnownIP. However, if the controller file is renamed to known_ips_controller.rb it (most likely) will stop working

What do you mean "stop working"? The controller is still the controller, whether it is handling routes for "/known_i_p" or "/known_ip"...

Another interesting example: if a model is generated with $ rails generate model known_i_p ... then it is broken from the beginning.

Well yes, the name of the model should be the correctly cased name of the model... "known_i_p" is not...

To make it work, it is necessary to rename its file from *known_i_p.rb* to *known_ip.rb*, and to add set_table_name 'known_i_ps' to it. Can the correspondence between file names and model names be specified manually in such odd cases?

I think the problem is you haven't actually said what you want to *do*. I don't know what "odd case" this shows. Do you mean you want to have a model called "KnownIp" but a table called "known_i_ps"? If so, why? What reason do you have for not having the table called "known_ips"? Or do you want your model called "KnownIP" but the model file called "known_ip.rb"? Again, what on earth for? What difference does the model's file name make in the scheme of things?

The controller is a totally different issue - you can call a controller anything you like, it's not a 1:1 mapping to a model.

Actually Alexey is right, using rails 3.0.5 then rails g model KnownIP generates models/known_ip and class KnownIp

Also rails g model ABCdEF gives ab_cd_ef.rb and class AbCdEf and rails g model ABCDEFG gives abcdefg.rb and class Abcdefg

all rather odd.

Colin

It appears that this may be the technique rails uses, first to get the table name from the model in the generate command String#tableize is used, then singularize is used on this to get the file name, and then camelize to get the class name, so

ruby-1.8.7-p302 > "KnownIP".tableize => "known_ips" ruby-1.8.7-p302 > "KnownIP".tableize.singularize.camelize => "KnownIp"

Since tableize uses ActiveSupport::Inflector.tableize it may be possible to override this for particular cases.

Colin

Something's wrong with your typing here or on the console, because your model should be "KnownIP" if you typed "$ rails generate model KnownIP". If the "p" is lower case in the model, you must have typed a lower case p...

Actually Alexey is right, using rails 3.0.5 then rails g model KnownIP generates models/known_ip and class KnownIp

Ah! Well, in that case I'll let the bug-reporting commence :slight_smile:

all rather odd.

Yes... must get into Rails 3. Contract ends next month so time for some learning (if only AWDwR4 is released at some point... ETA end of April, but it's moved back a few times in the last couple of months :-/

Michael Pavling wrote in post #990662:

Something's wrong with your typing here or on the console, because your model should be "KnownIP" if you typed "$ rails generate model KnownIP". If the "p" is lower case in the model, you must have typed a lower case p...

No, i typed "$ rails generate model KnownIP" and got a model named "KnownIp" in a file named "known_ip.rb".

What do you mean "stop working"? The controller is still the controller, whether it is handling routes for "/known_i_p" or "/known_ip"...

Sorry, i haven't tested this for controllers, but if there is a mismatch between a model name and its file name, the model is not working. Example: "KnownIP.create" gives "uninitialized constant KnownIP" if the model file is named "known_i_p.rb" and not "known_ip.rb". With controllers, which name should be used in the route, the name of the file, or the name of the controller? :slight_smile:

Another interesting example: if a model is generated with $ rails generate model known_i_p ... then it is broken from the beginning.

Well yes, the name of the model should be the correctly cased name of the model... "known_i_p" is not...

According to $ rails generate controller --help : "Pass the controller name, either CamelCased or under_scored, and a list of views as arguments." It is true that $ rails generate model --help does not say this, but i assumed it should have been the same...

I think the problem is you haven't actually said what you want to *do*. I don't know what "odd case" this shows. Do you mean you want to have a model called "KnownIp" but a table called "known_i_ps"? If so, why? What reason do you have for not having the table called "known_ips"? Or do you want your model called "KnownIP" but the model file called "known_ip.rb"? Again, what on earth for? What difference does the model's file name make in the scheme of things?

The controller is a totally different issue - you can call a controller anything you like, it's not a 1:1 mapping to a model.

I want to have a model KnownIP and a controller KnownIPs controller, and i want to choose myself how to name their files ("known_ip.rb" and "known_ips_controller.rb", for example). I also want to understand the rules and options about naming those files, in order not to run into some model name or controller name which would be *impossible* to store in *any* file :).

Alexey.

There is the same issue with migrations' names, but since they play an auxiliary role, i din't worry too much about their names...

... I want to have a model KnownIP and a controller KnownIPs controller, and i want to choose myself how to name their files ("known_ip.rb" and "known_ips_controller.rb", for example).

I have posted a question on the rails core list asking whether there is a bug in tableize or whether this is as expected. http://groups.google.com/group/rubyonrails-core/browse_thread/thread/c3b4ec662226e2a7?hl=en

I also want to understand the rules and options about naming those files, in order not to run into some model name or controller name which would be *impossible* to store in *any* file :).

You are entirely free to choose controller names and associated routes as you wish, neither has anything to do with model names. There is often a 1:1 relationship between models and controllers. You can therefore allow rails to call the model KnownIp but have the *controller* and routes as known_ips. Just make sure that in the controller you reference the model by its actual name (KnownIp).

In addition it is possible to override the table name for a model using set_table_name in the model. Whether it is valid to have a model KnownIP in a file known_ip.rb I do not know. Forget about the model generator and try it and see. Don't forget to remove any old files of similar names from the models directory.

Colin

... It appears that this may be the technique rails uses, first to get the table name from the model in the generate command String#tableize is used, then singularize is used on this to get the file name, and then camelize to get the class name, so

ruby-1.8.7-p302 > "KnownIP".tableize => "known_ips" ruby-1.8.7-p302 > "KnownIP".tableize.singularize.camelize => "KnownIp"

Since tableize uses ActiveSupport::Inflector.tableize it may be possible to override this for particular cases.

I think it is actually String#underscore that is causing the problem (this is called by tableize) ruby-1.8.7-p302 > "KnownIP".underscore => "known_ip"

The source of this can be seen at

At the head of this file is a statement that the rules will not be changed as this could cause existing apps to fail, which makes sense. I do not know how to override this for special cases (or if it is possible other than monkey patching).

My suggestion in the earlier post to manually create the model file and call the model what you want, while using set_table_name may well be the solution.

Colin

Colin Law wrote in post #990676:

I have posted a question on the rails core list asking whether there is a bug in tableize or whether this is as expected.

http://groups.google.com/group/rubyonrails-core/browse_thread/thread/c3b4ec662226e2a7?hl=en

Thanks!

You are entirely free to choose controller names and associated routes as you wish, neither has anything to do with model names. There is often a 1:1 relationship between models and controllers. You can therefore allow rails to call the model KnownIp but have the *controller* and routes as known_ips. Just make sure that in the controller you reference the model by its actual name (KnownIp).

In addition it is possible to override the table name for a model using set_table_name in the model. Whether it is valid to have a model KnownIP in a file known_ip.rb I do not know. Forget about the model generator and try it and see. Don't forget to remove any old files of similar names from the models directory.

I know this, my question is specifically about naming files where the classes are defined. In particular, if it is possible to define

  class KnownIPsController < ApplicationController   end

in a file named "known_ips_controller.rb".

I suspect that the answer is "No". Should the route be   match "see" => "known_i_ps#show" or   match "see" => "known_ips#show" in this case?

None works, the errors are, respectively,   uninitialized constant KnownIPsController and   Expected .../test_app/app/controllers/known_ips_controller.rb to   define KnownIpsController

Alexey.

My copy mailed last week. Order now, gerbils are standing by!

Walter

Colin Law wrote in post #990676:

I have posted a question on the rails core list asking whether there is a bug in tableize or whether this is as expected.

http://groups.google.com/group/rubyonrails-core/browse_thread/thread/c3b4ec662226e2a7?hl=en

Thanks!

You are entirely free to choose controller names and associated routes as you wish, neither has anything to do with model names. There is often a 1:1 relationship between models and controllers. You can therefore allow rails to call the model KnownIp but have the *controller* and routes as known_ips. Just make sure that in the controller you reference the model by its actual name (KnownIp).

In addition it is possible to override the table name for a model using set_table_name in the model. Whether it is valid to have a model KnownIP in a file known_ip.rb I do not know. Forget about the model generator and try it and see. Don't forget to remove any old files of similar names from the models directory.

I know this, my question is specifically about naming files where the classes are defined. In particular, if it is possible to define

class KnownIPsController < ApplicationController end

in a file named "known_ips_controller.rb".

ruby-1.8.7-p302 > "KnownIPsController".underscore => "known_i_ps_controller" so put it in a file called known_i_ps_controller.rb, and since ruby-1.8.7-p302 > "KnownIPsController".underscore.camelize => "KnownIPsController" then you should be ok, or at least you should get a bit further.

Colin

I know this, my question is specifically about naming files where the classes are defined. In particular, if it is possible to define

class KnownIPsController < ApplicationController end

in a file named "known_ips_controller.rb".

I suspect that the answer is "No".

For what it's worth you can declare any class in any file - however if you don't put classes where rails expects to find them then it won't be able to magically load them for you

Should the route be match "see" => "known_i_ps#show" or match "see" => "known_ips#show" in this case?

The routing bit and the class loading bit aren't really related (in that it doesn't matter what routes exist, when automatically requiring a file for you rails wants known_ips_controller.rb to define KnownIpsController)

Fred

Frederick Cheung wrote in post #990688:

For what it's worth you can declare any class in any file - however if you don't put classes where rails expects to find them then it won't be able to magically load them for you

Thanks, i think this answers my question. So, i need to put   require 'known_ips_controller.rb' somewhere? I'll try to figure it out from here.

By the way, if i rename the migration   class CreateKnownIps < ActiveRecord::Migration to   class CreateKnownIPs < ActiveRecord::Migration is there a way to make it run with   $ rake db:migrate ? Where to put   requre "20110402204538_create_known_ips.rb" in this case? Well, with migrations it seems more complicated and probably not worth the efforts anyway.

Alexey.