I have the following 2 models:
Parent Model:
class Babysitter < ApplicationRecord
has_many :jobs
has_many :babysitters, through: :jobs
Babysitter Model:
class Babysitter < ApplicationRecord
has_many :jobs
has_many :parents, through: :jobs
They have a has_many through relationship from the Job model:
Model Job:
class Job < ApplicationRecord
belongs_to :Babysitter, :touch => true
belongs_to :Parent
end
I now want to call babysitter.parents but have each parent also include the attribute salary (an attribute from the Jobs table).
Is this possible?
I tried:
babysitter.parents.includes(:jobs.salary)
Additionally is it possible to include the result in a fastJsonApi?
parents_including_salary = babysitter.parents.includes(:jobs.salary)
options = {
include: [:babysitter, :'parents_including_salary']}
json = Api::CampaignReportSerializer.new(otherData, options).serialized_json
I think you can use delegate to call the salary?
belongs_to :Parent
delegate :salary, to: :parent
you can try this
in your API can call parent.salary
Related
I have model BatchClass and SubjectTeacherBatchClass having attribues like below.
class SubjectTeacherBatchClass < ApplicationRecord
belongs_to :batch_class
belongs_to :user, optional: true
belongs_to :shift
belongs_to :session_batch
end
and
class BatchClass < ApplicationRecord
has_many :subject_teacher_batch_classes
has_many :subjects, through: :subject_teacher_batch_classes
has_many :teachers, source: :user, foreign_key: 'user_id', through: :subject_teacher_batch_classes
end
I want to access batch_class.teachers but with custom attributes like i.e.
batch_class.teachers.where(session_batch_id: session_batch.id, shift_id: current_shift.id)
The problem is that session_batch_id and shift_id are not attributes of User class (alias teacher) but are attributes of SubjectTeacherBatchClass class. (the through class)
Is there any better way to get teachers from batch_class passing those default attributes (session_batch and shift)
Looks like https://stackoverflow.com/q/18799934/1154044 question rather similar to yours.
According to your models, you can try this query
batch_class.teachers.
references(:subject_teacher_batch_classes).
where(subject_teacher_batch_classes: {
session_batch_id: session_batch.id, shift_id: current_shift.id
})
I would like a user be able to create a course(so it should belong to one user) and also be able to join another course that it haven't created by him.What is the proper associations between the course and the user ? I want to make the following model associations:
Class User < ActiveRecord::Base
has_many :courses
has_many :comments ,through: :courses
end
Class Course < ActiveRecord::Base
has_and_belongs_to_many :users #here i am not sure
has_many :comments
end
Class Comment < ActiveRecord::Base
belongs_to :courses
end
I think what you should be able to do something like:
Class User < ActiveRecord::Base
has_many :courses
has_many :course_users
has_many :subscribed_courses, through: :course_users, source: :course # I think you should be able to do foreign_key: :course_id, class_name: 'Course'
has_many :comments ,through: :courses
end
Class Course < ActiveRecord::Base
belongs_to :user
has_many :course_users
has_many :participants, through: :course_users, source: :user # I think you should be able to do foreign_key: :user_id, class_name: 'User'
has_many :comments
end
Class Comment < ActiveRecord::Base
belongs_to :courses
end
#course_users is a join table for courses and users
class CourseUser < ActiveRecord::Base
# inside here you could have several other connections e.g grade of a user in a course within this join model
belongs_to :user
belongs_to :course
end
If I'm understanding what you're saying - you need to have a third model - you can call it enrollment
For Course you would use belongs_to :user if each course is created as a user.
Your Enrollment model with have two HABTAM
Class Enrollment < ActiveRecord::Base
has_and_belongs_to_many :users
has_and_belongs_to_many :courses
end
(An Aside, if a course is going to be offered more than once, you'll have to add an additional model for each instance of the course and the enrollment will belong to that model, and not courses)
I am trying to associate a polymorphic model (in this case Product) to a dynamic class name (either StoreOnePurchase or StoreTwoPurchase) based on the store_type polymorphic reference column on the products table.
class Product < ActiveRecord::Base
belongs_to :store, polymorphic: true
has_many :purchases, class_name: (StoreOnePurchase|StoreTwoPurchase)
end
class StoreOne < ActiveRecord::Base
has_many :products, as: :store
has_many :purchases, through: :products
end
class StoreOnePurchase < ActiveRecord::Base
belongs_to :product
end
class StoreTwo < ActiveRecord::Base
has_many :products, as: :store
has_many :purchases, through: :products
end
class StoreTwoPurchase < ActiveRecord::Base
belongs_to :product
end
StoreOnePurchase and StoreTwoPurchase have to be separate models because they contain very different table structure, as does StoreOne and StoreTwo.
I am aware that introducing a HABTM relationship could solve this like this:
class ProductPurchase < ActiveRecord::Base
belongs_to :product
belongs_to :purchase, polymorphic: true
end
class Product < ActiveRecord::Base
belongs_to :store, polymorphic: true
has_many :product_purchases
end
class StoreOnePurchase < ActiveRecord::Base
has_one :product_purchase, as: :purchase
delegate :product, to: :product_purchase
end
However I am interested to see if it is possible without an extra table?
Very interesting question. But, unfortunately, it is impossible without an extra table, because there is no polymorphic has_many association. Rails won't be able to determine type of the Product.purchases (has_many) dynamically the same way it does it for Product.store (belongs_to). Because there's no purchases_type column in Product and no support of any dynamically-resolved association types in has_many. You can do some trick like the following:
class Product < ActiveRecord::Base
class DynamicStoreClass
def to_s
#return 'StoreOnePurchase' or 'StoreTwoPurchase'
end
end
belongs_to :store, polymorphic: true
has_many :purchases, class_name: DynamicStoreClass
end
It will not throw an error, but it is useless, since it will call DynamicStoreClass.to_s only once, before instantiating the products.
You can also override ActiveRecord::Associations::association to support polymorphic types in your class, but it is reinventing the Rails.
I would rather change the database schema.
I've a problem with an active record relation. I have a Content class and a Product Class defined in this way:
Class Content < ActiveRecord::Base
has_many :product_relations, as: :productable
has_many :products, through: :product_relations
end
Class Product < ActiveRecord::Base
end
Content.first.products return me the products associated to the contents, but I cannot create an association to build a query like Product.first.contents that return me all the contents associated to a product.
Update
I have also this class:
class ProductRelation < ActiveRecord::Base
belongs_to :product
belongs_to :productable, polymorphic: true
end
Solved
has_many :contents, through: :product_relations, source_type: "Content", source: :productable
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