I have three models offer_ticket, event and offer and have three their respective factories below are the models and factories are given i got error stack level too deep.
There is loop execute offer_ticket-to-event, event-to-offer and then offer-to-offer_tickets
suggest me a solution how to remove this error
offer_Ticket
class Offer Ticket < Active Record::Base
belongs_to :event
end
event
class Event < Active Record::Base
has_many :offers , dependent: :restrict_with_error
has_many :offer_tickets , dependent: :restrict_with_error
end
offer
class Offer < Active Record::Base
has_many :offer_tickets , dependent: :restrict_with_error
belongs_to :event
end
Their respective factories as given below
offer_tickets
Factory Girl define do
factory :offer_ticket do
venue_row_id 1
sale_id 1
status "available"
seat_number 1
association(:event)
end
end
events
Factory Girl define do
factory :event do |f|
f.name { Faker::Name.name }
f.starts_at { Faker::Date.backward(Random.rand(20)).to_date }
f.description { Faker::paragraph }
after(:build) do |event|
create(:offer, event: event)
end
end
end
offers
Factory Girl define do
factory :offer do
price 1
proxy 1
multiple 1
cancel-others 1
after(:build) do |offer|
create(:offer_ticket, offer: offer)
end
association(:event)
end
end
The most probable reason for this could be the dependency between your factories.
Suppose, you want to create an Event using factory-girl with the factories mentioned in the question. Doing FactoryGirl.create(:event) will try to create Offer (See :after_build of event factory) and ...
Creation of this offer will trigger :after_build of offer factory, where it would try to create OfferTicket ...
And in offer_ticket factory, it has defined an association :event, which will again try to create an Event. Hence, this will cause an infinite loop.
My suggestion would be to NOT use after_build to create new objects in your case. You can create them separately and then assign then to parent object. If you provide some rspec code, it might improve my answer.
Related
I am using rails and my models are described as:
class.rb:
has_many :class_registrations
class registrations.rb:
belongs_to :class
belongs_to :student
student.rb:
has_many :class_registrations
Now how can I get all the list of students for a specific class in registrations.rb: file.
The best way is add an has many through association in Class model
has_many :class_registrations
has_many :students, through: :class_registrations
And you can access all the students of a specific class
#class = Class.first
#class.students
#return all student of the first class
Remember that in rails you have access to all models from any model or controller, you can create a class or instance method that allows you to access all the students in a class from the class_registrations but I do not recommend it, it is better if you use the association from the controller or view that needs it.
for example, if you find an instance method to get all companions of an student in a class regitration, you can def an method in class_registrations.rb
def companions
Student.where("id = ?", self.student_id)
end
def students_of_class(class_id)
class = Class.find(class_id)
class.students
end
I've two models
class Article < ActiveRecord::Base
has_one :review
end
class Review < ActiveRecord::Base
belongs_to :article
end
Now I would like to have this method in Article
class Article < ActiveRecord::Base
has_one :review
def self.has_review?
end
end
I've tried with .count, .size....but I've errors...how can I do to have the following code working
#article = Article.find(xxx)
if #article.has_revew?
....
else
...
end
The reason why I need it is becaus I will have different action in views or controller, if there is one Review or none
Regards
class Article < ActiveRecord::Base
has_one :review
def has_review?
!!review
end
end
This just defines a method on the instance (def self.method defines a class method). The method tries to load review. If the review does not exist, it will be nil. !! just inverts it twice, returning true if a review exists or false if the review is nil.
Right now I'm working on a Rails app that has an Event model and this model has Category models as nested attributes.
My Event model has a state attribute which must change to certain value if it's nested categories reach a particular amount.
I tried to do this using the after_update callback in the Event model, but it didn't work. Does anyone have any idea?
Why it didn't work? Probably because it reached maximal recursion level.
Try something like this:
class Event < ActiveRecord::Base
attr_accessor :category_count_state_updated
has_many :categories
accepts_nested_attributes_for :categories
attr_accessible :categories_attributes
after_update :update_state
private
def update_state
unless self.category_count_state_updated
self.state = 'categories_count_reached' if self.categories.count == 5
self.category_count_state_updated = true
self.save
end
end
end
I have the following (simplified model) and wish to access the 'spent' value in the to_json method of the object, ideally as an attribute of the object.
class Task < ActiveRecord::Base
has_many :hours
def spent
self.hours.sum(:spent)
end
end
Is there a way to do this without defining a method and hacking the to_json method? I've been hunting for a way to use scope or by hacking the after_initialize method, but none of these methods provide a 'spent' value when using inspect or to_json on the model.
I need to solve this on models higher up the tree that use a has_many, through relationship too.
You can use the :methods parameter to to_json call.
object.to_json(:methods => :spent)
http://api.rubyonrails.org/classes/ActiveModel/Serializers/JSON.html
The best solution I could find to this was overriding the 'as_json' method to include the attributes that I needed, or to perform the logic required, (in this case the sum of the has_many relationship).
class Task < ActiveRecord::Base
...
def as_json(options = { })
options = {} if options.nil?
self[:job_id] = self.phase.job_id
self[:spent] = self.hours.sum(:spent)
super(options)
end
end
on a previous question, I was searching for a way to
dynamic valitating my models.
Advice on "Dynamic" Model validation
The solution that I got working is:
def after_initialize
singleton = class << self; self; end
validations = eval(calendar.cofig)
validations.each do |val|
singleton.class_eval(val)
end
end
On my actual app, I have 2 models
class Calendar < ActiveRecord::Base
has_many :events
end
class Event < ActiveRecord::Base
belongs_to :calendar
def after_initialize
singleton = class << self; self; end
validations = eval(calendar.cofig)
validations.each do |val|
singleton.class_eval(val)
end
end
end
As you can see, the validation code that should be added to the Event class lies on the Calendar field "config".
Works fine for a existing Event, but doesn't for a new record. That's because, at the time that after_initialize is called, the association doesn't exists yet.
I can't find a way to do that besides putting the config values on Event itself.
Any advices?
Tks!
You probably want to run your validation code during the validation phase, not the initialize phase. Try this:
class Calendar < ActiveRecord::Base
has_many :events
end
class Event < ActiveRecord::Base
belongs_to :calendar
validate do |event|
validations = eval(calendar.cofig)
validations.each do |val|
eval(val)
end
end
end