Rails 4 query a reference via n:n relation - activerecord

following structure
Production
belongs_to :offer
has_many :production_positions
has_many :products, through: :production_positions
Product
has_many :production_positions
has_many :productions, through: :production_positions
ProductionPosition
belongs_to :production
belongs_to :product
Now i want to get all offers which contains the product_id 1. How did i have to query the database?
To get the productions is quite easy:
Production.includes(:products).where("products.id" => 1)
but how do i get the offers which are referenced?
Offer.includes(:production).includes(:products).where("products.id" => 1)
the line above produces the following error:
Association named 'products' was not found on Offer

Add has_many :products, through: :production in your Offer class and try with the following:
Offer.select('offers.*').joins(:products).where('products.id = ?', 1)
I assumed you had has_one :production in your Offer class. You could add a scope to perform the query:
class Offer < ActiveRecord::Base
has_one :production
has_many :products, through: :production
scope :with_product_id, ->(id) do
select('offers.*').
joins(:products).
where('products.id = ?', id)
end
end
Example (Offers with Product 1):
Offer.with_product_id(1)

Related

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.

How to properly handle multiple model associations to different keys in Rails 4.0.8

I'm having the following problem while trying to model my application, it's basically a functionality to handle bills with multiple people, like sharing the rent or any other similar stuff, the deal is:
I have a user model and a billing model but can't find out how to build the associations.
A user has_many billings and billings belongs_to user but, also the billing has_many users, e.g. Tom registers a bill that is meant to be shared by Tom himself, Betty and Bob.
So that makes Tom the creditor and the other two become debtors in the billing.
I'm kinda lost at this point, how to consolidate these associations, dunno if any more information is needed or if it's clear enough, but will appreciate any help and update with any other information needed.
Thanks in advance,
---EDIT---
I've come to the following approach:
Class User < ActiveRecord::Base
has_many :billings, foreign_key: "creditor_id", dependent: :destroy
end
Class Billing < ActiveRecord::Base
belongs_to :creditor, class_name: "User"
has_many :debts, dependent: :destroy
end
Class Debt < ActiveRecord::Base
belongs_to :billing
has_one :user
end
I also tried to graphically model it for better understanding here: imgur
Would that all be correct?
Don't be afraid to use the options available to you in ActiveRecord. If your model naming is getting cluttered (Billing belongs to a User and has_many Users) then be more specific with the association labels and sort the links with options. The Rails Associations Guide is easy to Google and covers pretty much everything.
class User < ActiveRecord::Base
has_many :billings, :foreign_key => 'creditor_id'
has_many :debts, :through => :debtor_users, :source => :billing
end
class Billing < ActiveRecord::Base
belongs_to :creditor, :class_name => 'User'
has_many :debtors, :through => :debtor_users, :source => :user
end
class DebtorUser < ActiveRecord::Base
belongs_to :billing
belongs_to :user
end
You can extend the Billing model to have multiple creditors also simply by converting the belongs_to association into a has_many :through association following the same pattern as debtors just with a different join model (say CreditorUser).

ActiveRecord::HasManyThroughAssociationPolymorphicSourceError

I need a player to have many structures and the structure to belong to the player. Structure is a polymorphic relationship.
class Player < ActiveRecord::Base
has_many :player_structures
has_many :structures, :through => player_structures
end
class PlayerStructures < ActiveRecord::Base
belongs_to :structure, polymorphic: true
belongs_to :player
end
class StructureA < ActiveRecord::Base
has_one :player_structure, :as => :structure
has_one :player, :through => :player_structure
end
class StructureB < ActiveRecord::Base
has_one :player_structure, :as => :structure
has_one :player, :through => :player_structure
end
But if I pull out Player.first and ask for its structures, it gives:
ActiveRecord::HasManyThroughAssociationPolymorphicSourceError: Cannot have a has_many :through association 'Player#structures' on the polymorphic object 'Structure#structure'.
But it should be able to generate a SQL query where it finds all player_structures with its id, then fetches the structure based on the structure_id and structure_type. Why does this fail and how can I validly construct a polymorphic join table?
UPDATE
If I do what I want it to do manually, it works:
player_structures.collect(&:structure)
Rails, y u no do that?
I think you need to be more specific in defining your relationships in your Player model. For example:
class Player < ActiveRecord::Base
has_many :player_structures
has_many :structureas, :through => player_structures, :source => :structure, :source_type => 'StructureA'
has_many :structurebs, :through => player_structures, :source => :structure, :source_type => 'StructureB'
end
Then you can make a method that'll return all the structures defined in the relationships instead of having to access each one individually.

NameError: uninitialized constant - Un-allowed syntax in ActiveRecord?

I have two resources that I'm trying to join - Package and Listing through a join table SubmittedPackage. I'm using Ruby 1.9.3-p125 and Rails 3.2.1 with PostgreSQL 9.1.3. The models look as follows.
class Package < ActiveRecord::Base
has_many :submitted_packages
has_many :listings, :through => :submitted_packages
class Listing < ActiveRecord::Base
has_many :submitted_packages
has_many :packages, :through => :submitted_packages
class SubmittedPackages < ActiveRecord::Base
belongs_to :package
belongs_to :listing
In Rails Console I keep getting NameError: uninitialized constant Listing::SubmittedPackage
If I replace the SubmittedPackage resource with Drum it will work (this of course includes having the appropriate table created and so forth).
Is :submitted_packages in conflict with something in Rails or ActiveRecord?
Any ideas why this is breaking?
Thanks in advance!
UPDATE: As a work-around I explicitly defined the :class_name for the has many relationship in the Listing and Package model. This has at least gotten things working, however, it's still is unclear to me why it was necessary to begin with. What Rails or Ruby naming convention was being broken by :submitted_packages ?
class Package < ActiveRecord::Base
has_many :submitted_packages, :class_name => 'SubmittedPackages'
has_many :listings, :through => :submitted_packages
class Listing < ActiveRecord::Base
has_many :submitted_packages, :class_name => 'SubmittedPackages'
has_many :packages, :through => :submitted_packages
class SubmittedPackages < ActiveRecord::Base
belongs_to :package
belongs_to :listing
If SubmittedPackage is the JoinTable, I guess it should have many listings, but I'm seeing just many packages and many submitted_packages.
HTH

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

Resources