GitHub is home to over 20 million developers working together to host and review code, manage projects, and build software together.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
Already on GitHub? Sign in to your account
NameError in History/hist_paquets_mesures#show
Showing /var/www-opf/opf/app/views/history/hist_paquets_mesures/show.html.haml where line #19 raised:
uninitialized constant HistPaquetMesures::HistVersionsPaquetsMesure
The part of my (HAML) view causing this issue :
= debug @hist_paquet_mesures.hist_versions_paquets_mesures
I set up an exception for the special singular-plural names that I use in config/initializers/inflections.rb :
ActiveSupport::Inflector.inflections do |inflect|
inflect.irregular 'pub_liste_horizon', 'pub_listes_horizon'
inflect.irregular 'hist_paquet_mesures', 'hist_paquets_mesures'
inflect.irregular 'hist_projet_connexe', 'hist_projets_connexes'
inflect.irregular 'hist_version_paquet_mesures', 'hist_versions_paquets_mesures'
inflect.irregular 'hist_origine_modification', 'hist_origines_modification'
Pluralize , singularize and classify methods are working as expected on rails console :
"hist_versions_paquets_mesures".singularize => "hist_version_paquet_mesures"
"hist_versions_paquets_mesures".classify => "HistVersionPaquetMesures"
"hist_version_paquet_mesures".pluralize => "hist_versions_paquets_mesures"
My app/model/hist_paquet_mesures.rb model :
class HistPaquetMesures < ActiveRecord::Base
My app/model/hist_version_paquet_mesures.rb model :
class HistVersionPaquetMesures < ActiveRecord::Base
belongs_to :vers_origine, :class_name => 'HistOrigineModification', :foreign_key => 'hist_origine_modification_id'
# polymorphic association
has_one :comme_origine, :class_name => 'HistOrigineModification', as: :hist_origine
My app/controllers/history/hist_paquets_mesures_controller.rb controller :
class History::HistPaquetsMesuresController < ApplicationController
@hist_paquet_mesures = HistPaquetMesures.find_by_id(params[:id])
The weird thing is where the "s" go in "HistVersionsPaquetsMesure" of the error message : HistPaquetMesures::HistVersionsPaquetsMesure
Other weird things is that the association is working in the opposite direction (belongs_to) (i.e. : my_hist_version_paquet_mesures.hist_paquet_mesures)
Shouldn't it be HistPaquetMesures::HistVersionPaquetMesures ?
Why do I have this result ?
This is related to the inflector. To transform the association name into a class AR uses camelize.singularize. In your case this translates to "hist_versions_paquets_mesures".camelize.singularize # => "HistVersionsPaquetsMesure", which explains the error. If AR would perform the operations the other way around it would work: "hist_versions_paquets_mesures".singularize.camelize # => "HistVersionPaquetMesures".
"hist_versions_paquets_mesures".camelize.singularize # => "HistVersionsPaquetsMesure"
"hist_versions_paquets_mesures".singularize.camelize # => "HistVersionPaquetMesures"
The root of the problem is that the inflector behavior varies if you define your inflections camelcased or underscored. I'm not if this is actually expected behavior but the inflector code is generally frozen.
@fxn could you clarify?
Thanks for your quick answer.
Do you think it will cover any unidentified issue if I add as well the camelized irregular inflection ?
For now, as suggested here the workaround is to add the classname to the association :
has_many :hist_versions_paquets_mesures, :classname => HistVersionPaquetMesures
adding the :class_name option will solve this specific issue the problem in the inflector will still be present though. I guess I would add the camelized inflection too but I'm not sure if this leads to different problems. Let me know if you try it.
I tried with only the camelized inflection (without :class_name option) => it did work
I tried with only the :class_name option (without camelized inflection) => it did work
I tried with both camelized inflection and :class_name option => it did work too
There maybe side effects, but I couldn't detect any
If it can help to decide to apply a fix, I checked the classify method in ActiveSupport::Inflector
The logic is to singularize first, and then camelize :
# Create a class name from a plural table name like Rails does for table names to models.
# Note that this returns a string and not a Class. (To convert to an actual class
# follow +classify+ with +constantize+.)
# "egg_and_hams".classify # => "EggAndHam"
# "posts".classify # => "Post"
# Singular names are not handled correctly:
# "business".classify # => "Busines"
# strip out any leading schema name
If we follow the same logic. The issue is more likely to come from ActiveRecord, according to my trace :
activerecord (3.2.11) lib/active_record/inheritance.rb:111:in `compute_type'
activerecord (3.2.11) lib/active_record/reflection.rb:172:in `klass'
activerecord (3.2.11) lib/active_record/associations/association.rb:117:in `klass'
activerecord (3.2.11) lib/active_record/associations/association.rb:123:in `target_scope'
activerecord (3.2.11) lib/active_record/associations/association.rb:87:in `scoped'
compute_type method is melting my brain, but seems to follow a different logic from classify
I've run into this issue before, and it was pretty annoying - especially since the inflection works the other way (singular camelCase class name => plural underscored table name).
I ended up resolving it by monkey-patching derive_class_name on AssociationReflection (link) to this:
class_name = name.to_s
class_name = class_name.singularize if collection?
class_name = class_name.camelize
This accurately matches both classify (cited above) and reverses the calculation in table_name which is underscore-then-pluralize.
It may be valuable to fix this - it's likely to be entirely harmless, as anybody who has an association that would be affected is either hitting the bug or has worked around it with :class_name already.
For those facing this issue.
It is easier to make the workaround by adding the singluar/plural camelized form into the config/initializers/inflections.rb file, than adding a :class_name => YourSingularModel option into each models using the association facing this bug.
:class_name => YourSingularModel
Is there anything to be done here or is it ok to go with @bluebird-communication's suggestion?
@laurocaetano the behavior described in my previous comment is odd. I'd like to hear from @fxn before closing.
There are reasonable ways to avoid the issue so we are not pressured here.
@senny sure! Thanks :)
I have fixed this by explicitly overriding the plural version of the falsely interpreted inflection. In my case, I have a character that has_many :wealth, which translates to wealths, which is wrong.
inflect.plural /^(wealth)$/i, '\1'
Regression test for irregular inflection on has_many
Also add a Changelog entry