Cucumber Undefined Method / Model Inheritance - ruby-on-rails

I am receiving the following error, when running cucumber:
undefined method `overall_rating_id=' for #<OverallVote:0x102f1c4a0> (NoMethodError)
Relevant classes are:
class OverallVote < Vote
belongs_to :overall_rating
attr_accessible :overall_rating_id
end
class OverallRating < Rating
has_many :overall_votes
end
I thought that the setter method should be available as long as I set attr_accessible for the overall_rating_id field. Why doesn't it work?

Are you running cucumber in a separate environment? With it's own DB?
It sounds like your test/cucumber db is out of sync with your development schema (where you added this field)

Related

Undefined Class/Module when Serializing

I am storing an array of typed objects in an ActiveRecord model like:
class Store::Bin < ActiveRecord::Base
serialize :items, Array
end
class Store::Item
include Virtus.model
attribute :name, String
...
end
When I make a code change in development mode and refresh my browser, I get an undefined class/module Store::Item exception.
It seems like something is getting crossed up with the class loading. All files are in the app/models/store/... directory, properly named w/r to their camelcase name.
The same issue happens when using the rails console. reload! does not fix the issue in the console; instead I have to exit and restart the console.
Adding a type to the array seemed to solve the problem.... but caused an issue with the associated FactoryGirl factory.
class Store::Bin < ActiveRecord::Base
serialize :items, Array[Store::Item]
end
UPDATE: the real issue was that when a code change is made to store/bin.rb, that class gets auto-loaded, but the auto loader had no idea that Store::Item was a dependency.
THE REAL FIX: Declare the required dependency using require_dependency
require_dependency "store/item"
class Store::Bin < ActiveRecord::Base
serialize :items, Array
end
You should avoid the :: operator when defining classes because of Rails autoload problems. Instead, try
module Store
class Item
# ...
end
end
When you're not sure what's going on you can use Module.nesting to figure out how Rails interprets the hierarchy.

Manually adding data to a namespaced model in rails

I'm trying to manually add data to a table in rails using the rails console, but I keep getting a undefined local variable or method error.
The model is namespaced under ratings:
models/ratings/value_for_money_score.rb
class Ratings::ValueForMoneyScore < ApplicationRecord
end
To try and manually add a record to the database, I run the following in the console:
$ RatingsValueForMoneyScore.create(score: '1', description:"Terrible, definitely not worth what was paid!")
And I get this error: NameError: uninitialized constant RatingsValueForMoneyScore
I have tried a few different versions such as
RatingsValueForMoneyScores.create,
Ratings_ValueForMoneyScores.create,
ratings_value_for_money_scores.create but keep getting the same error. What am I doing wrong?
Try
::ValueForMoneyScore.create(score: '1', description:"Terrible, definitely not worth what was paid!")
The error is descriptive enough in this case, the class RatingsValueForMoneyScore pretty much doesn't exist. Check your namespace, you have a class name (which should be singular) Rating, and the module ValueForMoneyScore. You'd use either
(after renaming the class to Rating)
Rating.create(...)
or
ValueForMoneyScores.create(...)
Your syntax is equivalent to:
class Rating
module ValueForMoneyScores < ApplicationRecord
...
end
end
The answer was a combination of input, so collecting that in one answer.
My namespaces weren't properly set up (I was using "Ratings" rather than "Rating"), so I fixed this for the tables. My models then looked as follows:
models/rating.rb
class Rating < ApplicationRecord
end
models/rating/value_for_money_score.rb
class Rating::ValueForMoneyScore < ApplicationRecord
end
And then this command worked for creating records in the rating_value_for_money_score table
$ Rating::ValueForMoneyScore.create(score: '1', description: "Test")

has_one unitialized constant when using .build_

I have situation where an assignment has one training session associated with it
class Assignment < ActiveRecord::Base
has_one :trainingsession
end
class TrainingSession < ActiveRecord::Base
belongs_to :assignment
has_many :drills
end
I keep getting a uninitialized constant error when I'm trying to build an object with a has_one relationship
I'm using the following to build the training session in my controller
#activetrainingsession = #assignment.build_trainingsession
And that line blows up with the uninitialized constant
Something that seems like it should be straightforward!!
By convention, Rails uses camelize and underscore to switch between camel case and underscored representations. This means, in your case, that TrainingSession would be properly referenced as training_session (not trainingsession).
You need:
#activetrainingsession = #assignment.build_training_session
But, to follow said convention all the way through, it may be better as:
#active_training_session = #assignment.build_training_session

Rails: Creating Wrong Table Name With a Namespaced STI

I have a model which uses STI:
class Contributor::Name < Contributor::NameBase
...
end
From this model:
class Contributor::NameBase < ActiveRecord::Base
...
end
Whenever Contributor::Name gets instantiated, I receive this error:
Mysql2::Error: Table 'shelflives_development.contributor_basis_name_bases' doesn't exist: SHOW FULL FIELDS FROM `contributor_basis_name_bases`
It seems that instead of looking up the table contributor_name_bases, ActiveRecord is looking up contributor_basis_name_bases. Why is adding basis between contributor and name_bases? How can I get it to stop?
Ok, it's not a answer about why rails is adding 'basis' but it will work for you.
Use set_table_name 'contributor_name_bases' in your model.

Rails gets wrong class when two classes have the same name

In my Rails I have the following models:
A STI sub-class
class Subscription::Discount < Subscription
def self.new_with_url
...
end
end
and another model class (doing completely different things, this is a STI base class)
class Discount < ActiveRecord::Base
end
So in my controller, I uses Subscription::Discount when I create users:
#user.subscription = ::Subscription::Discount.new_with_url()
However it complains: undefined method 'new_with_url' for #<Class:0x007fbb499c6740>
I think Rails is not calling the right class with new_with_url. On top of that I am not sure what #<Class:0x007fbb499c6740> is. So, two questions:
Without renaming any model, how can I reference Subscription::Discount properly?
Why is the error message saying #<Class:0x007fbb499c6740>, I can understand if it is Discount instead of that anonymous class.
EDIT:
Here are all the relevant models:
app/model/discount.rb
app/model/coffee_discount.rb (CoffeeDiscount < Discount)
app/model/subscription.rb
app/model/subscription/discount.rb (Subscription::Discount < Subscription)
The method is named create_with_url but you're calling new_with_url.
Fix the method name.

Resources