rails belongs_to through via association - activerecord

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

Related

Sinatra how to include more than one belongs_to JSON?

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)

Joint table with optional relation

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

adding index in rails

I
I have added has_many and belongs_to after running rake db:migrate. I added these associations and again rake db:migrate. No index was generated. Can you please tell me why is that?
Below are my associations
class Developer < ActiveRecord::Base
has_many :evaluations
has_many :final_scores
belongs_to :supervisor
end
class Evaluation < ActiveRecord::Base
belongs_to :developer
belongs_to :supervisor
end
class FinalScore < ActiveRecord::Base
belongs_to :developer
end
class Supervisor < ActiveRecord::Base
has_many :developers
has_many :evaluations :through => :developers
end
Have a look at the official rails guide on this subject: http://edgeguides.rubyonrails.org/association_basics.html#the-has-many-association
There you can see that you need to change the generated migration file and add the field by yourself.
This blog helps to understand better. You may missed out something in migration file.

ActiveRecord: Has many through (twice)

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

how to traverse rails model to obtain a complex result(has_mas > has_many)

Maybe is simple problem that I don't see, but is a bit tricky to me right now
What I need is know which projects a user had bet.
I want to do something like:
some_user.bets.projects
my models are:
class User < ActiveRecord::Base
has_many :bets
end
class Project < ActiveRecord::Base
has_many :bets
end
class Bet < ActiveRecord::Base
belongs_to :user
belongs_to :project
end
So, just to be clear, starting from a user instance, how can I know which projects a user had bet.
In sql will be something like
select projects.name from users
inner join bets
on bets.user_id = users.id
inner join projects
on bets.project_id = projects.id
where users.id = 1;
how to make it work?
Update your User and Project classes as follows:
class User < ActiveRecord::Base
has_many :bets
has_many :projects, :through => :bets
end
class Project < ActiveRecord::Base
has_many :bets
has_many :users, :through => :bets
end
Then you can do this:
user = User.first # Find a user
projects = user.projects # and return the projects that have bets

Resources