Can't show select box - ruby-on-rails

I have 3 models:
Lending
Equipment
Category
Lending belongs_to equipment
Equipment belongs_to :category
Equipment has_many :lendings
Category has_many :equipments
I want to show a selectbox in lending's form with the categories.But there's not any association between Lending and Category models.I can't see an association between these two models(Lending and Category) but with Equipment and Category yes.
How do I do that? Ah I'm using simple form!
Excuse my english!

you have generated a textbook example of has_many :through:
http://guides.rubyonrails.org/association_basics.html#the-has-many-through-association
A has_many :through association is often used to set up a many-to-many connection with another model. This association indicates that the declaring model can be matched with zero or more instances of another model by proceeding through a third model. For example, consider a medical practice where patients make appointments to see physicians. The relevant association declarations could look like this:
class Physician < ActiveRecord::Base
has_many :appointments
has_many :patients, through: :appointments
end
class Appointment < ActiveRecord::Base
belongs_to :physician
belongs_to :patient
end
class Patient < ActiveRecord::Base
has_many :appointments
has_many :physicians, through: :appointments
end

You should be using delegation in this case. Add this line to your lending.rb file.
delegate :category, to: :equipment
This will return the concerned category.

Related

Is this database relation schema correct?

I made my first project and got into problem that I couldn't get the right category_information values for specific competitions category through relations. So I started thinking that this could be the wrong schema for this task, so my question - is it actually wrong?
Current Scheme:
Assuming the following relationships between models from your image.
class Competition < ApplicationRecord
has_many :categories
has_many :informations
has_many :category_informations, through: :categories
end
class Category < ApplicationRecord
belongs_to :competetion
has_many :category_informations
has_many :information, through: :category_informations
end
class CategoryInformation
belongs_to :catagory
belongs_to :information
end
class Information < ApplicationRecord
belongs_to :competetion
has_many :category_informations
has_many :catagory, through: :category_information
end
Model can relates with one_to_many_to_many using :through option
It explains a association used to set up a many-to-many connection with another model.
you can get the category_informations from competition like
Competition.first.category_informations
It is all for doing! Pretty good, right?
And you could do get information from category too
Category.first.informations
Actually wrong schema doesn't exist, just there exists some wrong association description.
You can get more usage to use association from docs at 2.3 section and 4.3 section
Assuming the following relationships between tables,
A competition has_many categories,
A competition has_many information,
A category has_many information,
A category has_many competition,
An information has_many category
You can use has_many_through relationships
class Category < ApplicationRecord
has_many :category_competitions
has_many :competitions, through: :category_competition
has_many :category_informations
has_many :informations, through: :category_informations
end
class Information < ApplicationRecord
has_many :category_informations
has_many :categories, through: :category_informations
end
class Competition < ApplicationRecord
has_many :category_competition
has_many :categories, through: :category_competitions
end
class CategoryCompetition < ApplicationRecord
belongs_to :category
belongs_to :information
end
class CategoryInformation < ApplicationRecord
belongs_to :category
belongs_to :information
end
By this way you can access,Categories of a particular competition by #competition.categories
This article might be helpful for you to understand associations better
https://www.sitepoint.com/master-many-to-many-associations-with-activerecord/

Is has_many still necessary when has_many through exists?

I have what I feel like is a super simple question, but I can't find an answer anywhere!
Question:
If I previously had a has_many relationship like this: has_many :wikis, do I keep this relationship if later on I create a has_many through relationship like the following?
has_many :collaborators
has_many :wikis, through: :collaborators
This is all in my User model.
Background:
In my rails app, I have a User model and a Wiki model. I just gave users the ability to collaborate on private wikis so I migrated a Collaborator model and then came the step to create the has_many through relationships. I wasn't sure if I still needed has_many :wikis after putting has_many :wikis, through: :collaborators.
The reason I am confused is because Users should still be able to create wikis without collaborators and I'm not sure how the has_many through relationship works under the hood.
Originally I had only User and Wiki with a one-to-many relationship.
# User model
class User < ApplicationRecord
...
has_many :wikis # should I delete this?
has_many :collaborators
has_many :wikis, through: :collaborators
...
end
# Collaborator model
class Collaborator < ApplicationRecord
belongs_to :user
belongs_to :wiki
end
# Wiki model
class Wiki < ApplicationRecord
belongs_to :user
has_many :collaborators, dependent: :destroy
has_many :users, through: :collaborators
...
end
Is has_many still necessary when has_many through exists?
has_many not necessary when presence has_many through like your model
has_many :wikis # should I delete this?
has_many :collaborators
has_many :wikis, through: :collaborators
should I delete this?
Yes, you can delete this one, you don't need this as the same belongs_to
From The has_many Association
A has_many association indicates a one-to-many connection with another model. You'll often find this association on the "other side" of a belongs_to association. This association indicates that each instance of the model has zero or more instances of another model. For example, in an application containing authors and books, the author model could be declared like this:
From The has_many :through Association:
A has_many :through association is often used to set up a many-to-many connection with another model. This association indicates that the declaring model can be matched with zero or more instances of another model by proceeding through a third model. For example, consider a medical practice where patients make appointments to see physicians. The relevant association declarations could look like this:
class Physician < ApplicationRecord
has_many :appointments
has_many :patients, through: :appointments
end
class Appointment < ApplicationRecord
belongs_to :physician
belongs_to :patient
end
class Patient < ApplicationRecord
has_many :appointments
has_many :physicians, through: :appointments
end
You can work with only has_many association without has_many :through, but this is one-to-many, this not many-to-many
The has_many Association (without has_many :through) is one-to-many connection with another model
The has_many :through Association is up a many-to-many connection with another model
Update
Look, one physician may have many patients, on the other hand, one patient may have many physicians if you use has_many association without through for patient then this called one-to-many association, that means one physician has many patients, on the other hand, one patient belongs to one physician, and now association looks like this
class Physician < ApplicationRecord
has_many :patients
end
class Patient < ApplicationRecord
belongs_to :physician
end
Update 2
The has_many through the standard format your models after edited
# User model
class User < ApplicationRecord
...
has_many :collaborators
has_many :wikis, through: :collaborators
...
end
# Collaborator model
class Collaborator < ApplicationRecord
belongs_to :user
belongs_to :wiki
end
# Wiki model
class Wiki < ApplicationRecord
has_many :collaborators, dependent: :destroy
has_many :users, through: :collaborators
...
end

usage of "has_many" vs "has_many, through" relation in rails

i'm new to both rails and web-dev.
currently i'm studding "active record Associations" in rails 4
and i got confused on usage of "has_many" vs "has_many, through" relation.
for example, if i have Physician, Appointment, and Patient model in my schema.(As rails guide provides)
and rails tutorial suggests me to do like this.
class Physician < ApplicationRecord
has_many :appointments
has_many :patients, through: :appointments
end
class Appointment < ApplicationRecord
belongs_to :physician
belongs_to :patient
end
class Patient < ApplicationRecord
has_many :appointments
has_many :physicians, through: :appointments
end
but what if i make relation like this
class Physician < ApplicationRecord
has_many :appointments
end
class Appointment < ApplicationRecord
belongs_to :physician
has_many :patients
end
class Patient < ApplicationRecord
belongs_to :appointment
end
i think both will work fine.
but i want to know whats the differences and why they made "has_many, through" relations.
thank you for reading my question.
has_many through is a way to join two unrelated, independent models/tables and to reduce duplicates/redundancy in tables, where has_many states more directive relation.
Maybe example with appointments and physicians isn't clear. I'll give a different one.
class Artist
has_many :paintings
has_many :purchases
has_many :buyers, through: :purchases
end
class Painting
belongs_to :artist
end
class Purchase
belongs_to :painting
belongs_to :buyer
end
class Buyer
has_many :paintings_buyers
has_many :painting, through: :purchases
end
Talking about your example.
First, there is no convenient way for you to get physician's patents. The only way is:
physician.appoitments.map(&:patient).uniq
Which will result in
poor performance
inability to filter entities with sql, only with ruby(again poor performance)
Also, did you notice I used uniq? That's because patient's table will have lots of duplicates when the same patients will be appointed multiple times to the same physician.

Rails 5: "belongs_to through" kind of association

Happy New Year to everyone!
I have classic has_many through association:
class Physician < ApplicationRecord
has_many :appointments
has_many :patients, through: :appointments
end
class Appointment < ApplicationRecord
belongs_to :physician
belongs_to :patient
end
class Patient < ApplicationRecord
has_many :appointments
has_many :physicians, through: :appointments
end
However now I need to add has_many association from class Appointment to some class Example, which is in belongs_to association with another model and would be in belongs_to association with class Example.
If possible, how to to set this kind of assosiation? Thank you.
Update
I don't understand, why this question is downvoted.
Here is what I need in class Example :
class Example < ApplicationRecord
belongs_to :appointment
belongs_to :model_bbb
end
Update 2
Ok, I figured out I can use solution from this answer. Basically I can drop "Appointment" model and have class Example like this:
class Example < ApplicationRecord
belongs_to :physician
belongs_to :patient
belongs_to :model_bbb
end
Then in Physician and Patient I can do has_many :examples and another through relationship. I did wanted to do some strange belongs_to through thing as I could have relatively small table of class Appointment, but class Example table is expected to be quite big. So my initial thinking was not to create extra column which will be duplicated for so many times.
You could just add a has_many or has_many through to your Appointment model class.
Keep in mind that belongs_to association is always on the table that has the foreign key. So if you're right at your modeling you should have an appointment_id, for instance, on the examples table.
There's no problem using the associative table in relationship with another. Actually the idea of using an intermediate table is to be able to store other information on it (otherwhise you would be doing HABTM).

How make categories relationships with several model?

I have next models: Articles, Announcements, Catalogs and Media.
For item of every model I need to create a subcategory and a category. I will plan to create a relationship table with two columns: parend_id and child_id, and a column for every model with category_id.
How many relationship models I should create?
One for all?
Or one relationship model for every model?
No need to create a relationship model instead just use belongs_to relationship
because you said following i guess belongs_to relations should do it
For item of every model I need create subcategory and category.
So just add subcategory_id and category_id in your tables: Articles, Announcements, Catalogs and Media and establish has_many belongs_to relationship
EDIT But if you insist for relationship model then I would suggest to use one relationship model for every model.
Last EDIT: I really think you should use belongs_to, has_many relation
Class Article < ActiveRecord::Base
belongs_to :category
belongs_to :subcategory
end
class Category < ActiveRecord::Base
has_many :articles
# the same relation(has_many) will be for Announcements, Catalogs and Media
has_many :subcategories
end
class Subcategory < ActiveRecord::Base
has_many :articles
belongs_to :category
end
In this way you can get all articles using category.subcategories.articles
If the category has only one Subcategory then change the relation between them to has_one and your syntax will become category.subcategory.articles
I would personally use a has_many :through relationship with a polymorphic association in a single join table:
#app/models/article.rb
Class Article < ActiveRecord::Base
has_many :categorizable_categories
has_many :categories, through: :categorizable_categories
end
class Article < ActiveRecord::Base
has_many :tags, as: :taggable,dependent: :destroy
has_many :categories, through: :tags
end
class Category < ActiveRecord::Base
has_many :tags, dependent: :destroy
has_many :articles, through: :tags, source: :taggable, source_type: 'Article'
end
class Tag < ActiveRecord::Base
belongs_to :taggable, polymorphic: true
belongs_to :category
end
This will allow you to call the categories for each model with the likes of #article.categories
To achieve the parent & child categories, I'd recommend using something like the Ancestry gem - you'd set up an ancestry column in your join table - basically allowing you to create relations between a model's categories directly

Resources