Uninitialized constant in view - ruby-on-rails

I have two models:
Post:
class Post < ActiveRecord::Base
has_many :exes
end
Exe:
class Exe < ActiveRecord::Base
belongs_to :post
end
What I am getting in my view on http://localhost:3000/posts/index is:
NameError in Posts#index
uninitialized constant Post::Ex
It says just Ex for some reason.
The code of line ruby is complaining on is <% post.exes.each do |exe| %> which looks right to me.
So I don't really know why this is happening. If have also checked the following as i thought this might be the reason but no:
2.0.0-p247 :004 > ActiveSupport::Inflector.pluralize('Exe')
=> "Exes"
2.0.0-p247 :005 > ActiveSupport::Inflector.singularize('Exe')
=> "Exe"
Thanks in advance!

Your problem is that ActiveSupport::Inflector is assuming that a word that ends in 'xes' in the plural form must end in 'x' in the singular form. See here for help on customizing pluralizations.
Update: Somehow I missed the last part of your question. You said you tried:
> ActiveSupport::Inflector.singularize('Exe')
but did you try:
> ActiveSupport::Inflector.singularize('Exes')

Define the inflector for this particular string in your project's inflections initializer:
# config/initializers/inflections.rb
ActiveSupport::Inflector.inflections do |inflect|
inflect.irregular 'Exe', 'Exes'
end
Remember that you'll need to restart your server before changes will take effect.

Related

Rails Papertrail - display who Was Responsible for last change

I'm using Devise and Papertrail and would like to display which user made the most recent update (documentation link).
In controller:
def show
# #history = #person.versions.last
#last_change = #person.versions.last
#user_who_made_the_change = User.find #last_change.whodunnit.to_i
end
In show page
<%= #user_who_made_the_change %>
However I get the resulting error:
undefined method `whodunnit' for nil:NilClass
in app/controllers/people_controller.rb:15:in `show'
Any help would be much appreciated, thanks
I prefer to modify initializer to kept template clean.
config/initializers/paper_trail.rb
PaperTrail::Rails::Engine.eager_load!
module PaperTrail
class Version < ::ActiveRecord::Base
belongs_to :user, foreign_key: :whodunnit
end
end
history.html.erb
<% #versions.each do |version| %>
<%= version.user.email %>
<% end %>
There are many reasons for omit save version data (configuration, save without callbacks, save from console ...)
I think you must check if you have the information to show:
def show
#last_change = #person.versions.last
#user_who_made_the_change = (User.find(#last_change.whodunnit.to_i) if #last_change && #last_change.whodunnit) || nil
end
This must do the trick.
I've done a bit of googling this evening about this topic. I simply wanted to be able to write something like #post.versions.last.user and get the devise User record (ie the person whodunnit that version).
The way that worked for me was creating the paper_trail.rb initializer with
PaperTrail::Rails::Engine.eager_load!
module PaperTrail
class Version < ActiveRecord::Base
include PaperTrail::VersionConcern
belongs_to :user, foreign_key: :whodunnit
end
end
Some solutions gave me errors including json col not set or something and/or undefined methodtimestamp_sort_order'`.
This is just what worked for me.
Other options included creating this in your app/models which I liked the idea of but never tried cause this 'worked' and I have other code I want to write :)

Rails Active Record Name Error

I'm facing the following error:
NameError at
uninitialized constant XController::Sheep
at this line
server = Sheep.find_by_id(id)
This is my setup:
Under models/sheep.rb
class Sheep < ActiveRecord::Base
has_many :kids
end
Under models/kid.rb
class Kid < ActiveRecord::Base
belongs_to :sheep # I tried adding , :class_name => 'Sheep' didn't do anything
end
Under config/initializers/inflections.rb
ActiveSupport::Inflector.inflections(:en) do |inflect|
inflect.uncountable 'sheep'
end
The table name is actually sheep I checked
What else should I check?
EDIT:
In the controller controllers/farm.rb I make two calls:
#kid = Kid.find_by_id params[:id]
#sheep = Sheep.find_by_id(id) # works only when adding :: as in the answer
You can try accessing this model's name with double colon:
server = Sheep.find_by_id(id)
# become
server = ::Sheep.find_by_id(id)
^^
Then it should work.
I don't have enough infos yet to tell why it is not working without the colons, but my intuition tells me that XController::Sheep suggests you have a problem in you Controller's names.

Manage acts_as_taggable tags with activeadmin

Is it possible? I trying:
ActiveAdmin.register ActsAsTaggableOn::Tag do
end
But i'm getting an error:
undefined method `per_page_kaminari' for ActsAsTaggableOn::Tag(id: integer, name: string, info: text):Class`
try it with:
ActiveAdmin.register ActsAsTaggableOn::Tag.class_eval do
....
end
in admin/tags.rb, also if you have will_paginate in your Gemfile you'll need this
#fix for active_admin
Kaminari.configure do |config|
config.page_method_name = :per_page_kaminari
end
put it in config/initializers/kaminari.rb , name of the file doesn't matter. Restart app.
Edit - another idea:
acts_as_tagable creates a table tags,
so you just create a model tag.rb in app/models
class Tag < ActiveRecord::Base
end
and in app/admin/tags.rb:
ActiveAdmin.register Tag do
end
I have used it this way and it works, can't show you the admin table. :) will post a screenshot soon.

rails 3.1 inflection problem

I have a Rails 3.1 app with the following 2 models
class Listing < ActiveRecord::Base
has_many :listing_saves
end
class Team < ActiveRecord::Base
has_many :listing_saves
has_many :saved_listings, through: :listing_saves, source: 'listing'
end
The Join model looks like this
class ListingSave < ActiveRecord::Base
belongs_to :team
belongs_to :listing
end
Mow I think that there is an inflection problem because whenever I try to run my tests I get the following error (this is an example of an error and the test that caused it)
it "should return the listing saves associated with the team" do
save = Factory :listing_save, listing: #listing, saver: #user, team: #team
#team.listing_saves.should include save
end
Failures:
1) Team listing_saves associations should return the listing saves associated with the team
Failure/Error: #team.listing_saves.should include save
NameError:
uninitialized constant Team::ListingSafe
# ./spec/models/team_spec.rb:55:in `block (3 levels) in <top (required)>'
as if Rails is singularizing listing_saves into listing_safe
Here are some custom inflectors I have tried (not all at the same time) (none of them work)
# config/initializers/inflections.rb
ActiveSupport::Inflector.inflections do |inflect|
inflect.plural 'saved_listing', 'saved_listings'
inflect.singular 'saved_listings', 'saved_listing'
inflect.plural 'listing_save', 'listing_saves'
inflect.singular 'listing_saves', 'listing_save'
inflect.singular 'listing_safes', 'listing_safe'
inflect.plural 'listing_safe', 'listing_safes'
inflect.irregular 'listing_save', 'listing_saves'
inflect.irregular 'saved_listing', 'saved_listings'
end
What can I do next?
Note: I found the this similar question but the answer doesn't seem to solve my problem
Edit
I followed the answer below so that I now have the following in my config/initializers/inflections.rb
ActiveSupport::Inflector.inflections do |inflect|
inflect.irregular 'listing_save', 'listing_saves'
end
When I open up a console session and run "listing saves".singularize I get "listing_save" as I would hope. However, it seems that at least part of my application doesn't get it, my tests still fail in the same way as before. (I swear I'm restarting my server and spork before I test/run the application!).
Edit 2
I wrote some tests for inflections in my app:
describe "inflection" do
it "should singularize listing_saves properly" do
"listing_saves".singularize.should == "listing_save"
end
it "should pluralize listing_save properly" do
"listing_save".pluralize.should == "listing_saves"
end
end
Now I have a situation where these tests pass fine, but other tests still fail with the same error I was having before
NameError:
uninitialized constant User::ListingSafe
Same app, same spork instance, same files loaded. Something weird is going on here!??
You need to define an irregular inflection:
# Test your inflections!
> "listing_save".pluralize
=> "listing_saves" # OK!
> "listing_saves".singularize
=> "listing_safe" # Ouch :(
# Make it smarter
ActiveSupport::Inflector.inflections { |i|
i.irregular 'listing_save', 'listing_saves'
}
# Test again
> "listing_saves".singularize
=> "listing_save" # Yay!
Ruby docs:
------------------------ ActiveSupport::Inflector::Inflections#irregular
irregular(singular, plural)
------------------------------------------------------------------------
Specifies a new irregular that applies to both pluralization and
singularization at the same time. This can only be used for
strings, not regular expressions. You simply pass the irregular in
singular and plural form.
Examples:
irregular 'octopus', 'octopi'
irregular 'person', 'people'
Edit:
Some further investigation - and it looks like others have stumbled upon this same problem also (inflections not working as expected with associations). So in the meantime you can set the class name manually:
has_many :listing_saves, :class_name => "ListingSave"
Someone else with the same problem, and an additional inflections tweak. Personally I'd go with the :class_name setting instead though:
Issue with custom inflections in Ruby on Rails 3.0.3

Getting a NameError with ActiveRecord and relationships

I've run into a problem when using a one to many relationship. I want to have each Series have one Publisher and that one Publisher has many Series.
This is my Publisher model:
class Publisher < ActiveRecord::Base
validates_presence_of :name
has_many :series
end
This is my Serie model:
class Serie < ActiveRecord::Base
belongs_to :publisher
end
This is the failing test:
test "a publisher should have a list of series" do
#publisher = Publisher.new :name => "Standaard Uitgeverij"
#series = [ Serie.new(:name => "De avonturen van Urbanus", :publisher => #publisher),
Serie.new(:name => "Suske en Wiske", :publisher => #publisher) ]
assert_equal #series, #publisher.series
end
The test fails on the last line with NameError: uninitialized constant Publisher::Series.
I tried to save the publisher and the series, but this did not work. I tried it with only one serie, but this gives the same error.
Since I'm just starting out with Rails and Ruby, I am at a loss here. What am I doing wrong?
To address your actual question as mentioned in your comment (how can I name my model "Series"?), you need to make the Rails' Inflector aware of this exception to its default pluralization rules.
Add the following to config/environment.rb:
ActiveSupport::Inflector.inflections do |inflect|
inflect.uncountable 'series'
end
This will let you name your model as Series. You can test that it's worked using script/console:
>> "series".pluralize #=> "series"
>> "series".singularize #=> "series"
—I have to say that I've just tried using The Pluralizer and it would appear that Rails has knowledge of how to handle the word series built-in. Try it for yourself.
I believe John's answer is the best one.
You can also directly specify the class name in the has_many declaration
has_many :series, :class_name => 'Serie'
Your has_many relationship name is fine, but your model name is wrong.
As the singular and plural of series are both series, you need to rename your model from Serie to Series. After that, everything should be fine.

Resources