Rails - Remove has_many relation when the parent is destroyed - ruby-on-rails

I have 3 models
HiringTag
class HiringTag < ActiveRecord::Base
attr_accessible :name, :staffroom_id
validates :name, presence: true
has_many :hiring_tag_applications
has_many :job_applications, through: :hiring_tag_applications
after_destroy { |application|
HiringTagApplication.destroy(application.job_applications.pluck(:job_application_id))
end
HiringTagApplication
class HiringTagApplication < ActiveRecord::Base
belongs_to :hiring_tag, dependent: :destroy
belongs_to :job_application
end
JobApplication
class JobApplication < ActiveRecord::Base
has_many :hiring_tag_applications
has_many :hiring_tags, through: :hiring_tag_applications
end
What I am trying to do: is when I destroy the HiringTag or JobApplication, I want the related data to be deleted in HiringTagApplication as you will notice I have a after_destroy inside HiringTag that call back does get executed but the error I get is:
Couldn't find HiringTagApplication with id=96453
96453 is not the id of HiringTagApplication but it is job_application_id
How can I correct this so the record can be deleted?

No need of after_destroy, just use dependent: :destroy correctly like:
class HiringTag < ActiveRecord::Base
has_many :hiring_tag_applications, dependent: :destroy
end
And
class JobApplication < ActiveRecord::Base
has_many :hiring_tag_applications, dependent: :destroy
end
& remove it from associated table
class HiringTagApplication < ActiveRecord::Base
belongs_to :hiring_tag
belongs_to :job_application
end
Now, whenever HiringTag or JobApplication gets deleted its associated HiringTagApplication will also be deleted

Related

Rails Active record joins query

class Inquiry < ApplicationRecord
belongs_to :user , dependent: :destroy
belongs_to :booking , dependent: :destroy
end
class Booking < ApplicationRecord
belongs_to :user
belongs_to :property
has_many :inquiries
end
class Property < ApplicationRecord
belongs_to :user
has_many :bookings, dependent: :destroy
end
I have these models where a user can create a property and after that he can do a booking of that property, and after that he can create an inquiry.
On the inquiry index page I want to display a property name through the booking table in which the id property is stored.
Can anyone help me with that?
#inquiries = Inquiry.joins(booking: : property)
This worked for me

Multiple associations in the has_many "through" model

I have a Products & Parts model which would each have multiple uploads, which are also polymorphic. Is it possible for me to have a single ItemUpload model to handle the association between the Products/Parts and Uploads, or do they need to be separate? I'd try myself just to see, but don't want to cause any potential headaches down the line! Note that I'm aware I need to do the source: and source_type: stuff to clean up the polymorphic association with has_many, but would like to clarify this point first before proceeding. Current models:
class Product < ApplicationRecord
has_many :uploads, as: :uploadable, dependent: :destroy
end
class Part < ApplicationRecord
has_many :uploads, as: :uploadable, dependent: :destroy
end
class Upload < ApplicationRecord
belongs_to :uploadable, polymorphic: true
end
What I would ideally like:
Class ItemUpload < ApplicationRecord
belongs_to :product, optional: true
belongs_to :part, optional: true
belongs_to :upload
end
Is that ok or would I need a separate ProductUpload and PartUpload model?
I would have thought your associations would look more like:
class Product < ApplicationRecord
has_many :item_uploads, as: :itemable, dependent: :destroy
has_many :uploads, through: :item_uploads
end
class Part < ApplicationRecord
has_many :item_uploads, as: :itemable, dependent: :destroy
has_many :uploads, through: :item_uploads
end
class Upload < ApplicationRecord
has_many :item_uploads
has_many :products, through: :item_uploads, source: :itemable, source_type: 'Product'
has_many :parts, through: :item_uploads, source: :itemable, source_type: 'Part'
end
Class ItemUpload < ApplicationRecord
belongs_to :itemable, polymorphic: true
belongs_to :upload
end
That should allow you to do:
product.uploads
part.uploads
upload.products
upload.parts
BTW, in reference to the link you provided:
Upload ≈ User
ItemUpload ≈ Membership
Product, Part ≈ Project, Group
The above follows the pattern in the linked article.

Rails belongs_to associations and destroy callbacks not seeing original record

I have the following 3 models:
class ExitSurveyResponse < ActiveRecord::Base
belongs_to :survey_response, dependent: :destroy
belongs_to :attendance
end
class SurveyResponse < ActiveRecord::Base
has_many :question_responses, class_name: 'SurveyQuestionResponse', dependent: :destroy
has_one :exit_survey_response, dependent: :destroy
end
class SurveyQuestionResponse < ActiveRecord::Base
attr_accessible :response
validates :response, length: { maximum: 255 }
belongs_to :survey_question
belongs_to :survey_response
before_destroy :destroy_attendance_cache
private
def destroy_attendance_cache
logger.debug('The following is nil because it was already deleted')
logger.debug("exit_survey_response: #{survey_response.exit_survey_response}")
end
end
The problem is, when I delete an ExitSurveyResponse, I need to modify the attendance record associated with it. But I need to do so in the SurveyQuestionResponse object when it is deleted. Problem is, if I do that, the ExitSurveyResponse is already deleted. Is there a way to delay the deleting of ExitSurveyResponses until after the dependents are destroyed?
To be clear, I always need to update the attendance when a SurveyQuestionResponse is destroyed. But a SurveyQuestionResponse can be destroyed either directly (easy to handle), when a SurveyResponse is destroyed or when an ExitSurveyResponse is destroyed.

many to many relation by Users and Files and ownership of it in rails

How can I add ownership in many to many relationships?
For example like this models.
class User < ActiveRecord::Base
has_many :editabilities, dependent: :destroy
has_many :files, through: :editabilities
end
class File < ActiveRecord::Base
has_many :editabilities, dependent: :destroy
has_many :users, through: :editabilities
end
class Editabilities < ActiveRecord::Base
belongs_to :user
belongs_to :file
end
And I want to add a one-to-many relationship to User-and-Files.
At first I thought it is best to add owner boolean column to Editabilities, but I have no idea how to handle it.
Secondly I thought if I make a new junction model Ownerships, then I can handle it same way as Editabilities. But I've got a uninitialized constant User::Ownership when I tried it with code like this.
class User < ActiveRecord::Base
has_many :editabilities, dependent: :destroy
has_many :ownerships, dependent: :destroy
has_many :files, through: :editabilities
has_many :owned_files, through: :ownerships, source: :file
end
class File < ActiveRecord::Base
has_many :editabilities, dependent: :destroy
has_many :ownerships, dependent: :destroy
has_many :users, through: :editabilities
has_one :owner, through: :ownerships, source: :user
end
class Editabilities < ActiveRecord::Base
belongs_to :user
belongs_to :file
end
class Ownerships < ActiveReord::Base
belongs_to :user
belongs_to :file
end
How can I implement a feature like this?
The only problems I see here are the classes Editabilities and Ownerships. By Rails convention model class names should be singular, not plural.
class Editability < ActiveRecord::Base
belongs_to :user
belongs_to :file
end
class Ownership < ActiveReord::Base
belongs_to :user
belongs_to :file
end
One way to quickly check your class names is by checking the result of the classify function:
> "editibilities".classify
=> "Editibility"
> "ownerships".classify
=> "Ownership"
The rest of the associations all look correct.
Your class should be named Ownership and not Ownerships.
ActiveRecord class names are normally singular and table names are plural.
Easier solution seems to add belongs_to association to File model. Because 1 File can have only 1 owner.
class File < ActiveRecord::Base
...
belongs_to :owner, class_name: 'User'
end
You will need to add owner_id column to files table.

Struggling with has_many :through

Suppose I have 3 Models like this (not sure if this is correct):
class User < ActiveRecord::Base
has_many :lessons
has_many :points, through: :progress
end
class Progress < ActiveRecord::Base
belongs_to :user
has_many :lessons
end
class Lesson < ActiveRecord::Base
belongs_to :progress
end
(The Progress table has user_id and lesson_id fields.)
How would I make it so calling #user.points would return the amount of entries into the Progress table. Also, how would I build a relationship?
class User < ActiveRecord::Base
has_many :progresses
has_many :lessons, through: :progresses
end
class Progress < ActiveRecord::Base
belongs_to :user
belongs_to :lesson
end
class Lesson < ActiveRecord::Base
has_many :progresses
end
First, you need to set up the association for progress on your User model, so that the through association will work:
class User < ActiveRecord::Base
has_many :lessons
has_many :progress
has_many :points, through: :progress
end
Then you'll need to define a method (or relation) of points on your Progress table. Or, if you simply want a count of records, you could do: #user.points.size

Resources