Has a relationship through four models? - ruby-on-rails

I'm having trouble setting up this association between my models.
A User has many Accommodations, and Accommodations have one User.
Accommodations have many Notifications, and Notifications have one Accommodation.
Requests have many Notifications.
How can I make it so that I can get all of the Requests for a given User ( that is, User -> Accommodations (each) -> Notification -> Request)?
Update:
Here's my current controller file:
class PanelController < ApplicationController
before_filter :login_required
def index
#accommodations = current_user.accommodations.all
#requests = Array.new
#accommodations.each do |a|
a.notifications.each do |n|
#requests << Request.where('id' => n.request_id)
end
end
end
end
And models:
models/user.rb
class User < ActiveRecord::Base
[snip]
has_many :accommodations
has_many :notifications,
:through => :accommodations
end
models/accommodation.rb
class Accommodation < ActiveRecord::Base
validates_presence_of :title, :description, :thing, :location, :spaces, :price, :photo
attr_accessible :photo_attributes, :title, :description, :thing, :location, :spaces, :price
has_one :photo
has_many :notifications
belongs_to :user
accepts_nested_attributes_for :photo, :allow_destroy => true
end
models/notification.rb
class Notification < ActiveRecord::Base
attr_accessible :accommodation_id, :request_id
has_one :request
belongs_to :accommodation
end
models/request.rb
class Request < ActiveRecord::Base
belongs_to :notifications
attr_accessible :firstname, :lastname, :email, :phone, :datestart, :dateend, :adults, :children, :location, :status
validates_presence_of :firstname, :lastname, :email, :phone, :datestart, :dateend, :children, :adults, :location
end

Something like this should work:
#reqs = []
#user.accommodations.all.each do |a|
#reqs << a.notification.request
end
Assuming this is correct:
class User
has_many :accommodations
end
class Accommodation
belongs_to :user
has_many :notifications
end
class Notification
belongs_to :accomodation
belongs_to :request
end
class Request
has_many :notifications
end
Using has_many :through will not work for multiple models, as seen here: Ruby-on-Rails: Multiple has_many :through possible?
But you can do something like this in your user model:
class User
has_many :accommodations
has_many :notifications,
:through => :accommodations
def requests
self.notifications.all.collect{|n| n.request }
end
end

Related

Rails 5 Active Model Serializer display has many conditions in JSON

In my project I have those models and relationships:
class Course < ApplicationRecord
has_many :segments, inverse_of: :course, :dependent => :destroy, :autosave => true
accepts_nested_attributes_for :segments, :allow_destroy => true
end
class Segment < ApplicationRecord
validates :data ,presence: true, if: :segment_is_video?
validates :segment_type ,presence: true
validates_presence_of :course
belongs_to :course, inverse_of: :segments
has_many :questions
accepts_nested_attributes_for :questions, :allow_destroy => true
def segment_is_video?
segment_type == 'Video'
end
end
class Question < ApplicationRecord
validates_presence_of :segment
belongs_to :segment, inverse_of: :questions
end
I want to display the data field only if the type is Video, and I want to display questions array only if type field is Quiz. I'm using Active Model Serializer for that but it's not working. the data still displaying when the type is Quiz and the question array doesn't show at all.
this is my code for the serializers:
class CourseSerializer < ActiveModel::Serializer
attributes :id, :title, :author
has_many :segments
def root
'Course'
end
end
class SegmentSerializer < ActiveModel::Serializer
attributes :id, :unit_id, :unit_title, :name, :segment_type, :data
belongs_to :course
has_many :questions, if: -> { isQuiz }
def root
'Segments'
end
def include_data?
object.segment_type == 'Video'
end
def isQuiz
object.segment_type == 'Quiz'
end
end
class QuestionSerializer < ActiveModel::Serializer
attributes :id, :question, :answer1, :answer2, :answer3, :answer4, :correct
belongs_to :segment
def root
'Question'
end
end

How do I access the extra attribute on join table in my show page?

My models look like this:
class Project < ApplicationRecord
has_many :comments
has_many :contractor_projects
has_many :contractors, through: :contractor_projects
validates_presence_of :title, :contract_number, :category, :project_start_date, :project_end_date, :substantial_completion_date, :category, :solicitation_number, :project_officer, :location
accepts_nested_attributes_for :contractor_projects
end
class Contractor < ApplicationRecord
has_many :contractor_projects
has_many :projects, through: :contractor_projects
validates :name, presence: true
validates :email, presence: true, uniqueness: true
end
class ContractorProject < ApplicationRecord
belongs_to :contractor
belongs_to :project
end
The ContractorProject model has an extra attribute #bid_status that I want to reflect on project's show page but it does not appear even though it's in the params when i raised it.
below is sample method for your case
def show
#project = Project.find(params[:id]
#contractors = #project.contractors
end
inside show.html.erb, you have to loop it, since it may get more than one records
<% #contractors.each do |contractor| %>
<%= contractor.bid_status %>
<% end %>

Unable to find rails association Model

I am attempting to do a query via a junction table, though Rails is given me the below error
Venue Model
class Venue < ActiveRecord::Base
attr_accessible :address, :latitude, :longitude, :name, :phone, :suburb, :state, :country
after_validation :geocode
has_many :orders, through: :venues_orders
geocoded_by :full_address
def full_address
[address, suburb, state, country].compact.join(', ')
end
end
Order Model
class Order < ActiveRecord::Base
attr_accessible :fulfilled, :item, :placed, :person_id, :special_instructions, :priority, :flag, :milk
belongs_to :person
belongs_to :venue
Venues Orders Model
class VenuesOrders < ActiveRecord::Base
attr_accessible :order_id, :venue_id
end
class Venue < ActiveRecord::Base
has_many :orders, through: :venues_orders
has_many :venues_orders
end
class Order < ActiveRecord::Base
has_many :venues, through: :venues_orders
has_many :venues_orders
end
class VenuesOrders < ActiveRecord::Base
belongs_to :venue
belongs_to :order
end
For more details read : RailsGuides
Another advice: The convention for creating a join table is lexical ordering. Like, OrdersVenues not VenuesOrders

Validates uniqueness record per user per lesson // Rails 4

Problem: I want to have only 1 UserLesson per User per Video
because I'm building a tracking system (progress system) User shall be able to see how many lessons are remaining lesson/total lesson and also when marked as completed shall add css
I send the data from the view to the controller:
<%= link_to 'Mark as completed', user_lessons_path(#user_lesson, user_lesson: {user_id: current_user.id, lesson_id: #lesson.id}), :method => :post, class: 'btn btn-primary-big' %>
The controller receives data and launch the create method
class UserLessonsController < ApplicationController
before_filter :set_user_and_lesson
def show
end
def create
#user_lesson = UserLesson.create(user_lesson_params)
if #user_lesson.save
flash[:success] = "You rock! Keep up ;)"
redirect_to(:back)
else
flash[:success] = "You have already completed this lesson"
redirect_to(:back)
end
end
private
def user_lesson_params
params.require(:user_lesson).permit(:user_id, :lesson_id, :completed)
end
end
Here is the model relationship
class UserLesson < ActiveRecord::Base
belongs_to :user
belongs_to :lesson
# validates_uniqueness_of :user_lesson, :scope => [:user, :lesson]
end
class Lesson < ActiveRecord::Base
has_one :lecture, through: :chapter
belongs_to :chapter
end
class User < ActiveRecord::Base
has_many :enrollments
has_many :user_lessons
has_many :lectures, through: :enrollments
accepts_nested_attributes_for :enrollments
end
class Enrollment < ActiveRecord::Base
belongs_to :user
belongs_to :lecture
validates :lecture, uniqueness: { scope: :user, message: "should happen once per user" }
end
class Lecture < ActiveRecord::Base
belongs_to :category
has_many :lessons, through: :chapters, dependent: :destroy
has_many :chapters
belongs_to :teacher
# For course user relationship
has_many :enrollments
has_many :users, through: :enrollments
accepts_nested_attributes_for :enrollments
accepts_nested_attributes_for :chapters
end
class Chapter < ActiveRecord::Base
has_many :lessons
belongs_to :lecture
accepts_nested_attributes_for :lessons
end
My guess was to validates uniqueness of user-lesson per user and lesson. However can't seem to work got the error message.
Add this validation to your model to ensure uniqueness by user scope:
validates :lesson_id, :uniqueness => {:scope=>:user_id}

how to List date in order of number of another data?

class Subject < ActiveRecord::Base
attr_accessible :name, :teacher_id
has_and_belongs_to_many :courses
belongs_to :teacher
has_many :users, :through =>:feedback
has_many :feedbacks
end
class Course < ActiveRecord::Base
attr_accessible :name
has_many :users
has_and_belongs_to_many :subjects
validates :name, presence: true, length: { maximum: 50 }
end
class Feedback < ActiveRecord::Base
attr_accessible :rating, :recommendations, :strengths, :subject_id, :user_id, :weaknesses
belongs_to :user
belongs_to :subject
end
class User < ActiveRecord::Base
attr_accessible :course_id, :email, :gender, :name, :password, :password_confirmation
has_secure_password
belongs_to :course
has_many :feedbacks
has_many :subjects, :through =>:feedback
end
There is a join table between course and subjuct
I am a student and freshman in rails,I have some problem in this final project
How to
List subjects in order of number of feedbacks.
List students with no feedbacks.
I have no idea how to do it. Thanks very much
I am providing solution for two queries you need:
List subjects in order of number of feedbacks
#subjects = Subject.find(:all, :include=>:feedbacks).sort_by { |p| p.feedbacks.size}
List students with no feedbacks
User.find(:all, :include => :feedbacks, :conditions => "feedbacks.id is null")

Resources