I have three models:
Company;
Investor;
Broker.
in real world each investor can invest in many companies, but in some he/she can invest with broker assistance.
I made it through joint table.
def change
create_join_table :companies, :investors do |t|
t.references :broker, index: true, optional: true
end
end
class Company < ApplicationRecord
has_and_belongs_to_many :investors
end
class Investor < ApplicationRecord
has_and_belongs_to_many :companies
end
class Broker < < ApplicationRecord
has_many :companies
end
How should I configure my models/migrations to have next information:
Company.first.investors.first.broker
broker is not belongs to investor, in each company/investor pair can be different broker.
Use has_many through associations and add the broker on the join model. After adding the proper migrations your models will look like this:
class Company < ApplicationRecord
has_many :company_investors
has_many :investors, through: :company_investors
end
class Investor < ApplicationRecord
has_many :company_investors
has_many :companies, through: :company_investors
end
class Broker < ApplicationRecord
has_many :company_investors
has_many :companies, through: :company_investors
end
class CompanyInvestor < ApplicationRecord
belongs_to :broker
belongs_to :investor
belongs_to :company
end
With this models, you can add Investor to Company associations with or without Broker, and also discriminate them. I also recommend naming the join model (which in my code I named CompanyInvestor) a more significant name, like Investment
Related
I have 3 models
first fight belongs to blue_fighter and red_fighter
class Fight < ActiveRecord::Base
belongs_to :blue_fighter
belongs_to :red_fighter
end
then my other 2 models are like this
blue_fighters
class BlueFighter < ActiveRecord::Base
has_many :fights
has_many :red_fighters, through: :fights
end
red_fighters
class RedFighter < ActiveRecord::Base
has_many :fights
has_many :blue_fighters, through: :fights
end
Now in my application controller
class ApplicationController < Sinatra::Base
set :default_content_type, 'application/json'
get '/fights' do
fights = Fight.all
fights.to_json(include: :blue_fighter)
end
end
im only getting the :blue_fighters i want to include both the :blue_fighter and :red_fighter
i tried something like this it doesnt work
fights.to_json(include: :blue_fighter && :red_fighter)
Is it possible to access objects more than one model away?
For example let's say I have
class Contact <ActiveRecord:Base
has_many :interactions
end
class Interaction <ActiveRecord:Base
belongs_to :contact
belongs_to :course_presentation
end
class CoursePresentation <ActiveRecord:Base
has_many: interactions
belongs_to :course
end
class Course <ActiveRecord:Base
has_many :course_presentations
end
Right now I know I could write a through relationship via contacts to course presentations and then get all the course related to all the course presentations or I could do
contact.interactions.map{ |i| i.course_presentation.course }
I would like to be able to pull courses related to a contact directly so ... e.g.
contact.courses
Is this possible?
Yes, I believe so. Just add the following:
class Contact < ActiveRecord::Base
has_many :interactions
has_many :course_presentations, through: :interactions
has_many :courses, through: :course_presentations
end
I'm modeling a lessons table, the lesson belongs to a user, the teacher and creator of the lesson, and also, the lesson can have many students, which are also users.
So it would be something like this
class Lesson < ActiveRecord::Base
belongs_to :user
has_many :users
end
I'd like to call the first user teacher, and the collection of users students, I've read the documentation at http://guides.rubyonrails.org/association_basics.html but I can't quite find what I want.
This should have what you want: http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-belongs_to
I think you want the class_name option:
class Lesson < ActiveRecord::Base
belongs_to :teacher, class_name: "User"
has_many :students, class_name: "User"
end
In your current code, all users could be the "owner" (teacher) of a lesson, instead you should have two additional classes "student" and "teacher" both having a 1:1 relation to the "user" class.
This would fit better:
class Teacher < ActiveRecord::Base
has_one :user
end
class Student < ActiveRecord::Base
has_one :user
end
class Lesson < ActiveRecord::Base
belongs_to :teacher
has_many :students
end
I'm on rails 3.0 and trying to figure out what would be the proper way to setup a belong_to :through relationship (which) I know is not possible. Here's an example:
class ParentCompany < ActiveRecord::Base
has_many :subsidiaries
has_many :employees, :through => :subsidiaries
end
class Subsidiary < ActiveRecord::Base
belongs_to :parent_company
has_many :employees
end
class Employee < ActiveRecord::Base
belongs_to :subsidiary
belongs_to :parent_company, :through :subsidiary # <-- I know this is invalid
end
I know I can solve it by doing:
class Employee < ActiveRecord::Base
def parent_company
subsidiary.parent_company
end
end
However, I'd like to know if I can do the above via associations.
You can use delegate to accomplish this without using an association
class Employee < ActiveRecord::Base
belongs_to :subsidiary
delegate :parent_company, to: :subsidiary
end
There are Things in Places which I'm looking to find. One Thing could be in many different Places, and many Things can be in one Place.
class Thing < ActiveRecord::Base
has_and_belongs_to_many :places
end
class Place < ActiveRecord::Base
has_and_belongs_to_many :things
end
I want to record the Finds of my Users so that I know where they found what.
class Find < ActiveRecord::Base
belongs_to :user
belongs_to :places_thing # Is this depluralization correct?
end
class User < ActiveRecord::Base
has_many :finds
# Now, how can I link in the Things the user has found? Like this?
has_many :found_things_in_places, :class_name => :places_things, :through => :finds
has_many :things, :through => :thought_things_in_places
end
Does this seem right? is it efficient? Thanks.
I think you were on the right track, the big change I'd make is that rather than having a join table (places_things) you should make it a proper model. I decided to call this an existence.
The data only exists in one place, so it's properly normalized. These relationships are clear and will be easy to manage. I think it's efficient.
class Place < ActiveRecord::Base
has_many :existences
has_many :things, :through => :existences
end
class Thing < ActiveRecord::Base
has_many :existences
has_many :places, :through => :existences
end
class Existence < ActiveRecord::Base
belongs_to :place
belongs_to :thing
end
class Find < ActiveRecord::Base
belongs_to :user
belongs_to :existence
end
class User < ActiveRecord::Base
has_many :finds
has_many :existences, :through => :finds
has_many :things, :through => :existences
end
You'll need rails 3.1 to do the nested has many through's like we did in User.
BTW the correct association declaration should be: belongs_to :places_things