How to save a student from the model? - ruby-on-rails

I have two models, one is called Employer and the other is called Student. Employers can view student profiles. How can I let employers save student profiles they like?
What I mean by that is, when the employer views a student profile and they like it, they must be able to click "save" and a link to that user profile will be saved and displayed on the employers profile. So when the employer goes to his own profile page, there will be a section called "Saved students" and links to the profiles of the students will be there.
I was thinking I add an array called "saved_profiles" to the employer model and then add a "save" button to the student profile. When an employer clicks it, the web address they are looking at right now, gets added to the saved_profiles array. By web address, I mean like "www.mywebsite.com/students/jake-madison". I'm not completely sure how to implement this though, any help on how to make this happen will be greatly appreciated.

An array on the "employers" table is what we would call a "denormalized" strategy. A "normalized" strategy would involve storing that save as a record in a join table. The denormalized solution is quick and easy - at first. It can cause headaches later on. So let's talk about the normalized solution using Rail's magical has many through association.
rails
class Employer
has_many :employer_students
has_many :students, through: :employer_students
class Student
class EmployerStudent
belongs_to :student
belongs_to :employer
database
table: students
columns: id, name
table: employers
columns: id, name
table: employer_students
columns: employer_id, student_id
When an employer "saves" a student's profile, we create a record in the employer_students table, linking that employer to that student. Then, when we want to see the students that an employer has saved, we do a join.
employer.students

Related

Explanation on Rails Associations - Rails 4

i'm new to rails and your help and advise would be much appreciated as i am finding this challenging
Aim: i want the creator of the event to be able to select more than one user as
hosts for a created event (just like how facebook allows the creator of
a page to be be able to select users as admins of a created page). Is the below how my model and schema should be displayed?
i was aiming to build something like this image. Event1 i can select Ian & Jesse as hosts, Event2 i can also select Ian again as a host and select Emma
This is how i imagine it so far to be built (your guidance would be much appreciated):
models
user.rb
has_many events
event.rb
belongs_to user
host.rb
belongs_to user
has_many events
schema
users
name
email
events
title
address
user_id
hosts
user_id
event_id
Started writing this as a comment but realised it was getting too wordy.
your model is broken ... an event has many users .. it doesn't belong_to a single user.
What you have is a many to many relationship between users and events which needs resolving through a join table (aka associative/junction table). You have gone some way to resolving this with the hosts table though this goes against the rails convention.
What you want is something like:
models
user.rb
has_and_belongs_to_many :events
event.rb
has_and_belongs_to_many :users
and create a join table that references the two models
users table
name
email
events table
title
address
events_hosts table
user_id
event_id
The rails convention is for the join table to be named by joining the two names of the tables it is joining lexically ordered - i.e. events before hosts, concatenated together to give events_hosts.
Alternatively, you can also create a join model if you prefer:
EventHost
belongs_to :user
belongs_to :event
and modify the has_and_belongs_to_many to has_many :event_hosts in the other two models - the database schema will remain the same.

User Model with Listings Rails - How to reach?

I have a Boat Model and its Models such as Brand, Model and Year. I have also User model and I would like to connect them by adding migrations to User model of boat_id and I added belongs_to :boat and has_many :boats to User model. But I can not reach User.first.boat.name from the console even though I am able to reach Boat.first.brand.name.
When I try User.first.boat.name. Console gives an error saying;
NoMethodError: undefined method `boat' for #<User:0x0000000665dc30>
Btw: Boat Model includes model_id brand_id and year_id.
EDIT1:
Or should i remove Boat model and add model_id brand_id and year_id to User model directly.
EDIT2:
I would like to be able to reach User.first.boat.brand.name or User.first.boat.year.nameor User.first.boat.model.name
EDIT3:
Every boat has one brand, year and model. But user can have many boats
EDIT4:
What i will do is;
User can sign up and login
Then User press the link list my boat.
He/she saves the boat then the page renders to User Profile
In the User profile I do not know how to get current user boat name year etc. That is why I am confused. Sorry for the misunderstanding
I think you're confused about how Rails associations work in conjunction with how they are stored in the database. If a User can have many boats, then the foreign key needs to be on the boats table. Currently you have boat_id in the users table, this should be removed and a user_id column needs to be added to the boats table as per Matt's answer.
Reference
To achieve what you're trying to do, you'll need to setup your models in the following manner:
class User
has_many :boats
...
end
class Boat
belongs_to :user # table has a user_id column
...
end
Then you can access a boat's brand using user.boats.first.brand.name
Run rails generate migration, then fill in the change method as follows:
def change
add_column :boats, :user_id, :integer
end
Then run rake db:migrate.
You user model has_many boats, so you need the boats table to refer to users. It's probably worth reading the Rails guide for ActiveRecord associations to get a better feel for how this works: http://guides.rubyonrails.org/association_basics.html#the-has-many-association

Rails: working with associations and join-table in a many-to-many relationship

I have a User model and a Product model with a many-to-many association and in both models I have "has_and_belongs_to_many"
I understand that this allows me to work with relations like this:
user = User.first
user.products #shows all products bought by a user
and
product = Product.first
product.users # show all users who bought that product
But there might be a product which has not been bought by any user yet, so this product will be in products table but not in the user_products join-table.
How do I return only user-products associations which have been saved in the join table?
Also, say I want to create a product and at the same time define that it has been bought by - belongs to - first and second user. I thought of:
User.all[0..1].each {|usr| usr.product.create(name: "tv")}
Is this the correct way to imply an association and populate the join-table with a record for it?
What if, as I said above, I have a product that is in products table but still no User had bought it, and now a user buys it: how can I express this so that later I can do
user.products
and see that product?
How do I return only user-products associations which have been saved in the join table?
You can't, because you've decided to use has_and_belongs_to_many where the join table is not accessible at all. Consider using has_many through relation.
Is this the correct way to imply an association and populate the join-table with a record for it?
It should be:
User.limit(2).each {|usr| usr.products.create(name: "tv")}
or
User.limit(2).each {|usr| usr.products << Product.create(name: "tv")}
What if, as I said above, I have a product that is in products table but still no User had bought it, and now a user buys it: how can I express this so that later I can do
Simply user.products.reload

How to properly structure relationship from pre-established choices (or new if not exists) in rails?

This is a quick and simple question of thinking the database. I have a User model and a Hotel model.
Each user has a hotel and can select one of those from the hotels table OR add hotel name and address if his hotel is not found on the table. What is the best way to do that? I don't want users to be able to create hotels. So what I thought was:
1- Users table
-- User.hotel-name
-- User.hotel-address
2- Hotels table
-- Hotel.name
-- Hotel.address
If the user selects an existing hotel, it would "copy" the info from this hotel. But that does not seem correct. Any help?
Thanks
The best way to do that and normalizing de database is create another table HotelUsers including the hotels created by Users.
You check if hotel exist in HOTEL table.
Next check if hotel exists in HOTELUSERS with de id of user.
create new HOTELUSER copy of Hotel or new by User
HOTELUSERS
userId
name
address
ANOTHER WAY
You also can have a relationship many to many in USERS <-> HOTEL and store one parameter on HOTEL table for knowing when hotel is create by user.
Sounds as though each user belongs to a hotel (in the database relational way anyway), so you would have a user model:
class User < ActiveRecord::Base
belongs_to :hotel
...
end
And a hotel model:
class Hotel < ActiveRecord::Base
has_many :users
...
end
That means that the the user table would have a hotelId column, where you would store the hotel it relates to.
Where the user is associated with a hotel in the code, something like:
... #sanitize name & address from params
user.hotel = Hotel.first_or_create(name: name, address: address)
....
This would set the users hotel to either one that already exists with that name and address or creates a new one

Structure movie lists

I'm trying to set up a proper database-design, but I'm stuck.
Here is what I'm trying to save.
Every user can define a vote history list from imdb looking like this.
Two users can define the same list.
First I want to be able to save each list as an imdb_vote_history_list - list.
class ImdbVoteHistoryList < ActiveRecord::Base
has_and_belongs_to_many :vote_history_list
has_and_belongs_to_many :movies
# Fields
# id (Integer) - defined by the user
end
Each list should be unique and is being defined by it's ID (given in the link).
Each list has and belongs to many movies, as in the code above.
Each user should be able to pick a name for every list.
So instead of saying
Each imdb_vote_history_list belongs_to user
I create a new relation called vote_history_list.
class VoteHistoryList < ActiveRecord::Base
has_and_belongs_to_many :imdb_vote_history_lists
belongs_to :user
# Fields
# name (String)
end
Here the user can pick any name for the list, without interference with other user's names.
Is this a good way to store the data?
From the theoretical database design view this is the right approach.
For example the entity relationship model describes it this way. You can have relationships between entities and attributes at those relationships. If you map those to a relational model (database tables) you get a table for the relationship containing references to both entites and all additional information.
This is what theory can tell us about it :)

Resources