Cascading multiple models - ruby-on-rails-4

I'm deleting a Place and it's cascading the rows of PlaceUpload, but I also would like to cascade the rows of Match and TagCostumer while I am deleting a Place. How can I do that?
class Place < ActiveRecord::Base
has_many :place_uploads
end
class PlaceUpload < ActiveRecord::Base
belongs_to :place
has_many :matches
has_many :tags_customers
end
class TagsCustomer < ActiveRecord::Base
belongs_to :place_upload
belongs_to :tag
end
class Match < ActiveRecord::Base
belongs_to :place_upload
belongs_to :customer
end

The solution was to use destroy and create a callback to automatically do a deep cascading.
class Place < ActiveRecord::Base
before_destroy :delete_children_objects
has_many :place_uploads, :dependent => :destroy
protected
def delete_children_objects
#places = PlaceUpload.where(place_id: id)
#places.each do |place|
TagsCustomer.where(place_upload_id: place.id).destroy_all
Match.where(place_upload_id: place.id).destroy_all
end
end
end

Related

Rails includes with has_many through giving avoid eger loading n+1 by bullet gem

My Models are like:
class ThreeDModel < ApplicationRecord
has_many :three_d_model_animations
has_many :animations, through: :three_d_model_animations
has_many :three_d_model_images, dependent: :destroy
has_many :three_d_garments
has_one :model_efm
has_one :model_edm
end
2nd:
class ThreeDModelAnimation < ApplicationRecord
belongs_to :animation
belongs_to :three_d_model
validates_presence_of :animation_file
#validates_presence_of :motion
mount_uploader :animation_file, ThreeDModelAnimationUploader
enum animation_motions: {
'Run': 'run',
'Turn Aroun (100 Frames)': 'turn_around_100_frames',
'Turn Around (300 Frames)': 'turn_around_300_frames',
'Walk (58 Frames)': 'walk_58_frames',
'Walk (92 Frames)': 'walk_92_frames'
}
end
3rd:
class Animation < ApplicationRecord
has_many :three_d_model_animations
has_many :three_d_models, through: :three_d_model_animations
mount_uploader :video, AnimationVideoUploader
validates_presence_of :video
validates :name, :frames, :loop_start, :loop_end, presence: true
end
Now my query is:
#model = ThreeDModel.where(id: params[:id]).includes(:model_efm, :model_edm, :three_d_model_images, :three_d_model_animations, :animations).last
which gives the following message by the bullet gem:
AVOID eager loading detected
ThreeDModel => [:three_d_model_animations, :animations]
is there a better way so that n+1 could be avoided. Thanks in advance

Undefined method for ActiveRecord_Associations_CollectionProxy

I have several models, which are connected to each other:
class InsurerPayment < ActiveRecord::Base
belongs_to :insurer
belongs_to :company
has_many :contracts
end
class Insurer < ActiveRecord::Base
belongs_to :company
has_many :contracts
has_many :insurer_payments, dependent: :destroy
end
class Contract < ActiveRecord::Base
belongs_to :company
belongs_to :insurer
belongs_to :insurer_payment
end
When I do commissions = current_company.contracts.pluck(:commission).sum in my insurer_payments_controller, I get the sum of commission for all the contract related to my current company. But I need to get the sum of commission that belongs to insurers of my current company. Doing something like commissions = current_company.insurers.contracts.pluck(:commission).sum gives me an error: undefined method `contracts' for # Insurer::ActiveRecord_Associations_CollectionProxy:0x007f92450f79c0. How can I get the result I need? Thanks ahead.
You can try this:
current_company.insurers.map { |ins| ins.contracts.pluck(:commission).sum}
You are getting this type of error because when you hit current_company.insurers is return an array, and you hit contracts on this array this is incorrect.

Link models through acts_as_taggable_on rails

I have a model Product which has_many :taxons, through: :classifications. How to implement acts_as_taggable_on to implement the tagging of products with the names of taxons instead of the the tags from the tag table? Is it possible or not?
#app/models/product.rb
class Product < ActiveRecord::Base
translates :name
accepts_nested_attributes_for :translations, allow_destroy: true, reject_if: :all_blank
# Associations
has_many :classifications, inverse_of: :product, dependent: :delete_all
has_many :taxons, through: :classifications
end
#app/models/classification.rb
class Classification < ActiveRecord::Base
self.table_name = 'products_taxons'
# Associations
belongs_to :product, inverse_of: :classifications
belongs_to :taxon, inverse_of: :classifications, touch: true
end
#app/models/taxon.rb
class Taxon < ActiveRecord::Base
translates :name
globalize_accessors
has_many :classifications, inverse_of: :taxon, dependent: :delete_all
has_many :products, through: :classifications
end

Rails 4: how to use form_for (has_many :through with extra attributes)

I have a Store model, Product model, and a StoreProduct model to form a many-to-many relationship between stores and products.
The StoreProduct model, on top of store_id and product_id, has an attribute price:float.
I'm struggling to figure out how I can design a form to create a new product given the store. Is it better off making a form for a new StoreProduct object? What is the conventional way of doing this?
store.rb
class Store < ActiveRecord::Base
validates :name, presence: true
has_many :store_products
has_many :products, through: :store_products
end
product.rb
class Product < ActiveRecord::Base
validates :name, presence: true
validates_numericality_of :price, on: :create
has_many :reviews
has_many :users, through: :reviews
has_many :store_products
has_many :stores, through: :store_products
end
store_product.rb
class StoreProduct < ActiveRecord::Base
belongs_to :store
belongs_to :product
end

rails scope through has_many association

I have two models for Show and Performance (show as in a play or comedy show). They are associated like this in the models:
class Show < ActiveRecord::Base
has_many :performances, :dependent => :destroy
accepts_nested_attributes_for :performances
end
class Performance < ActiveRecord::Base
belongs_to :show
end
In the Performance model there is a datetime called :start_time.
How do I define a scope in the model which returns all Shows with at least one performance whose :start_time is in the future?
Also, how do I define a scope that returns all Shows that do not have any performances in whose :start_time is in the future?
class Show < ActiveRecord::Base
has_many :performances, :dependent => :destroy
accepts_nested_attributes_for :performances
scope :shows_with_pending_performance, includes(:performances).where("performances.start_time >= ? ", Date.today)
end
class Performance < ActiveRecord::Base
belongs_to :show
end