Hi I have three tables like the following:
class Workitem < ActiveRecord::Base
has_many :effort
attr_protected
end
class Effort < ActiveRecord::Base
attr_protected
belongs_to :workitem
belongs_to :person
end
class Person < ActiveRecord::Base
attr_accessible :given_name, :mgrid, :surname, :id
has_many :effort
end
The idea is to keep track of how many days a person has spent on a particular work item through efforts table. Could somebody verify if my relationships are correct? But this doesn't seem to work. Am I missing something here?
Also, I can't understand the has_many :through kind of associations. Can somebody please give me an idea if that is what I'm supposed to use in this case?
You would usually have the child as a plural object:
class Workitem < ActiveRecord::Base
has_many :efforts
attr_protected
end
class Person < ActiveRecord::Base
attr_accessible :given_name, :mgrid, :surname, :id
has_many :efforts
end
And I'd recommend using attr_accessible instead of attr_protected
If a Foo had many Bars and the Bars belonged to many Foos, it might look like this:
class Foo < ActiveRecord::Base
has_many :foo_bar
has_many :bars, through => :foo_bar
end
class Bar < ActiveRecord::Base
has_many :foo_bar
has_many :foos, through => :foo_bar
end
class FooBar
belongs_to :foo
belongs_to :bar
end
Something like that anyway. There's a load of help on Railcasts here
Also, there's a trillion examples on SO.
Hope that helps
Related
What I want to do is to get all the
My model:
class User < ActiveRecord::Base
has_many :classes
has_many :professors, :through=>:classes
has_many :cars
has_many :carmodels, :through=>:cars
end
class Professor < ActiveRecord::Base
has_many :classes
has_many :users, :through=>:classes
end
class Class < ActiveRecord::Base
belongs_to :user
belongs_to: professor
end
class Car < ActiveRecord::Base
belongs_to :user
belongs_to :carmodel
end
class Carmodel
has_many :cars
has_many :users, through=>:cars
end
what I want to do is, given a certain Car and Professor, to find all users which contain them.
for example
u1=carmodel.users
u2=professor.users
result=[]
u1.each do |us|
if u2.include? us
result.push us
end
end
Of course this is just an example... I would like to keep working with ActiveRecords(avoid turning it to an array) and, of course, a more optimal solution... I can't seem to find any.
You need to do something like this:
User.joins(:carmodels).joins(:professors)
Thanks for the previous answer! Here is the resulting code:
carmodel #Variable for the wanted carmodel
professor #Variable for the wanted professor
result=User.joins(:carmodels).joins(:professors).where(carmodel:{id:carmodel.id},professors:{id:professor.id})
Thanks again!
I have a polymorphic relationship setup as follows:
class Industry < ActiveRecord::Base
attr_accessible :name
has_many :user_industries
end
class UserIndustry < ActiveRecord::Base
attr_accessible :industry_id, :industriable_id, :industriable_type
belongs_to :industry
belongs_to :industriable, polymorphic: true
end
class Applicant < ActiveRecord::Base
has_many :user_industries, as: :industriable
end
class Employer < ActiveRecord::Base
has_many :user_industries, as: :industriable
end
I have a search feature and I'd like to fetch, for example, all Applicants that have a certain Industry. Does Rails provide a convenient way to do this, or do I have to write some methods myself?
from the comment that you wrote i assume, that you want to write a join query like this (untested):
Applicant.joins(:user_industries).where('user_industries.industry_id' => self.id).pluck('applicants.id')
I have three models which look something like this:
Class User < ActiveRecord::Base
has_many :comments
end
Class Comment < ActiveRecord::Base
belongs_to :user
has_many :votes
end
Class Vote < ActiveRecord::Base
belongs_to :comment
end
Now I want to get all the votes associated with a user's comments like so:
#user.comments.votes
But this throws the error:
undefined method `votes' for #<ActiveRecord::Relation:0x3f6f8a0>
This seems like it should work, but I suspect ActiveRecord is coughing on the deeper has_many relationship. I've hacked together an SQL query that gets the desired results, but I suspect there's a cleaner way using purely ActiveRecord. Any tips?
You should use a has_many :through association
In your case it would be
Class User < ActiveRecord::Base
has_many :comments
has_many :votes, :through => :comments
end
Class Comment < ActiveRecord::Base
belongs_to :user
has_many :votes
end
Class Vote < ActiveRecord::Base
belongs_to :comment
end
And then simply get the votes with
#user.votes
Try this:
Vote.joins(comment: :user).where(users: {id: #user.id})
I have the models shown below. I need to store some details that are specific a person and a house (first_viewed:date, opening offer:decimal, etc). I feel like these should belong to the PersonHouse model but I'm not certain enough. Any suggestions?
class Person < ActiveRecord::Base
has_many :houses, through: :person_houses
has_one :favorite_house, through: :person_houses
end
class PersonHouse < ActiveRecord::Base
belongs_to :house
belongs_to :person
end
class House < ActiveRecord::Base
has_many :house_people
has_many :people, through: :person_houses
end
I could do something like this to get all the details but perhaps there is a more effient way.
#house = House.find(1)
#house.house_people.each do |hp|
puts hp.person.name
puts hp.first_viewed
puts #house.address
end
I think your assumption is correct. If the data is relevant to the relationship between a person and a house, then yes it belongs on this model. The only recommendation I would make is to rename this model to a name that better describes what the relationship is. It doesn't have to be the concatenation of the two models it joins. I don't know exactly what the model is going to be ultimately used for, but SelectedHouse, HouseProspect or something along those lines might work.
You can also delegate properties to the house or person models:
class PersonHouse < AR::Base
belongs_to :person
belongs_to :house
delegate :address, :to => :house, :prefix => true
delegate :name, :to => :person, :prefix => true
end
person_house.address
person_house.person_name
I have two models: User and HairColor. A user has only one hair color, but can have many hair color preferences. What's the best way to model this?
Here's what I started to do:
#models/user.rb
class User < ActiveRecord::Base
belongs_to :hair_color
has_many :preferences,
has_many :hair_colors, :through => :preferences
end
#models/hair_color.rb
class HairColor < ActiveRecord::Base
has_many :users
end
#models/preference.rb
class Preference < ActiveRecord::Base
belongs_to :user
belongs_to :hair_color
end
Is using has_many :through the right approach? Also what if I want to extend this to other attributes such as "eye color"? (A user has one eye color, but can prefer many eye colors"
There will be a limited amount of hair colors, so the preference table needs to have a hair_color_id and be set up like so:
#models/user.rb
class User < ActiveRecord::Base
has_one :hair_color
has_many :preferences
end
#models/hair_color.rb
class HairColor < ActiveRecord::Base
belongs_to :user
belongs_to :preference
end
#models/preference.rb
class Preference < ActiveRecord::Base
belongs_to :user
has_many :hair_color
end
I believe that's correct. Let me know if you run into any snags.
When you add eye color or any other characteristic, you'll probably have to do something different with preference. I'd have 4 columns at that point: id, user_id, foreign_id, foreign_type
foreign_id would be the id from the eye_color/hair_color table, and foreign_type would be "eye" or "hair" or something. Then in your model, you'd have something like this:
#models/hair_color.rb
class HairColor < ActiveRecord::Base
belongs_to :user
has_many :preferences, :foreign_key => :foreign_id, :conditions => { "preferences.foreign_type" => "hair" }
end
That gets a little crazy, but it's the most DRY way of doing it. You'd put the same thing in your eye_color.rb and just replace "hair" with "eye" for the foreign_type.