I am having trouble wrapping my head around what I'd consider a more complex association and was hoping someone could help point me in the right direction.
I have four models:
user
profile
feed_group
feed
All 4 of these obviously have their own fields and data stored within. My goal is to have a summary database table called "user_detail" (I am open to calling it something different if Rails has its conventions), which has the following 4 fields:
user_id
profile_id
feed_group_id
feed_id
What would my model associations look like?
Thanks.
You can create the model through a migration like this:
rails g model UserDetail user:references profile:references feed_group:references feed:references
Within the created file models/user_detail.rb you will find the relations:
class UserDetail < ActiveRecord::Base
belongs_to :user
belongs_to :profile
belongs_to :feed_group
belongs_to :feed
end
Also, add references to UserDetail in all the referenced models, eg. in models/user.rb add has_many :user_details, etc.
As I read your question, that's all you need.
Related
I have two classes in my Rails API database, that I have just created a joining table for. I had seeded both classes previously so they have data. Now I would like to seed the joining class with id's from the existing data.
This is what the models look like for the first two classes:
class Stakeholder < ApplicationRecord
has_many :project_stakeholders
has_many :projects, through: :project_stakeholders
end
class Project < ApplicationRecord
has_many :project_stakeholders
has_many :stakeholders, through: :project_stakeholders
end
This is the model for my joining class:
class ProjectStakeholder < ApplicationRecord
belongs_to :project
belongs_to :stakeholder
end
Now I have two questions:
How to populate the joint class with data from the two first classes (project_id and stakeholder_id).
How can I check in the Rails console for values in the ProjectStakeholder class?
I have researched and tried different options from Stackoverflow but they don't seem to work. Rails guides do not provide an answer either, from what I have seen. Would be very grateful for some ideas!
You can just assign stakeholders to the project after creation
Project.first.stakeholders << Stakeholder.limit(5)
Project.second.stakeholders << Stakeholder.limit(5).offset(5)
You can check it in console in different ways:
Project.first.stakeholders.pluck(:id)
ProjectStakeholder.first
Sorry maybe for the stupid question but I'm new. When I create tables using this command rails g model Post title:string description:text. How can I further make a connection between another table by?
Or will have enough in the models table select belongs_to? And thus the connection will be already established and you will not need to install anything in the migration.
If you want to "connect" the posts table (Post model), with whatever you already have, like a users table, to make an one-to-many association you can use the references as a kind of type, which will generate an entry on the migration file for creating a foreign key column on your (posts) table.
create_table :posts do |t|
t.references :user
...
end
So the command could be:
$ rails generate model Post title:string description:text user:references
There I'm using user as an example, it can be any other.
The model generated will already have the belongs_to association specified, like:
class Post < ApplicationRecord
belongs_to :user
...
What you need then is to add the has_many association in the User model:
class User < ApplicationRecord
has_many :posts
...
I am working on building a portfolio section in my website right now. I have it set where a portfolio has one category that is associated with it.
class Portfolio < ApplicationRecord
has_one :category
end
I am trying to access the category attribute name in the show view for the portfolio , but I am getting this error.
SQLite3::SQLException: no such column: categories.portfolio_id: SELECT "categories".* FROM "categories" WHERE "categories"."portfolio_id" = ? LIMIT ?
This is what is in the view:
<li><i class="icon_link"></i><span>Category: </span><%= #portfolio.category.name %></li>
I remembering using this syntax before and not having any problems with it. Any help would be great. I tried to find this question on here =, but could not make of them work.
Rails conventional naming for has_one/belongs_to associations is - if you have category_id column in Portfolio then "a portfolio belongs_to a category" and "a category has one portfolio". You need to rewrite your models as:
class Portfolio < ApplicationRecord
belongs_to :category
class Category < ApplicationRecord
has_one :portfolio
After that #portfolio.category.name should work fine.
Update: Possibly "a category has many portfolios", when the models will be:
class Portfolio < ApplicationRecord
belongs_to :category
class Category < ApplicationRecord
has_many :portfolio
Whenever you have an association in rails, there has to be at least two entites (or models) involved in that association. In your particular case, you've associated a Portfolio with a Category via the has_one association. However, you need to specify the association on the Category end as well. So in your Category.rb model class, you need to write:
class Category < ActiveRecord::Base
belongs_to :portfolio
# other stuff
end
There's one more step to ensuring that the association is working properly. You need to make sure that the categories table in your database has a field called portfolio_id. If it does, then you should be good to go! If it doesn't then do the following:
Type rails generate migration addPortfolioIdToCategory in your terminal
Open up the migration file and ensure it looks like this:
def change
add_column :categories, :portfolio_id, :integer
end
Now run rake db:migrate from your terminal
If you reload your server, your problem should be solved!
NOTE
The model that specifies the belongs_to association must have the primary key attribute in the corresponding database table. In your case, if the Category model has the belongs_to association, then the categories database table must have the field titled portfolio_id.
It's complaining portfolio_id doesn't exist on your categories table. Verify your migration file for categories. Given the foreign key is set on categories it should work. Rails has one association
Hopefully I don't get flamed for this one too bad - I've tried my very hardest to find an answer to no avail.
I was wondering if someone could help me figure out how to properly declare associations in Ruby on Rails (3). At the moment, I have 3 models:
#room.rb
class Room < ActiveRecord::Base
has_many :check_ins
end
#check_in.rb
class CheckIn < ActiveRecord::Base
belongs_to :user
belongs_to :room
end
#user.rb
class User < ActiveRecord::Base
has_one :check_in
end
So far, I haven't done any migrations to add foreign_key columns to any of my tables (does Rails do this for you?).
I'm confused about why the command CheckIn.first.user returns nil whereas the command User.first.check_in returns SQLite3::SQLException: no such column. The same happens with respect to CheckIn.first.room and Room.first.check_ins, respectively. What would I need to do in order to have User.first.check_in return the CheckIn object associated with the first user and Room.first.check_ins return the set of CheckIns associated with the first Room?
Any help would be GREATLY appreciated.
Charlie
How did you originally generate these models? Did you just make the model files, or did you use rails' model generator (which also generates a migration for you)?
#room.rb
class Room < ActiveRecord::Base
has_many :check_ins
end
#check_in.rb
class CheckIn < ActiveRecord::Base
belongs_to :user
belongs_to :room
end
#user.rb
class User < ActiveRecord::Base
has_one :check_in
has_one :room, :through => :check_in
end
In db/migrations/34612525162_something_something.rb You need to make sure you have migrations that set these tables up for you. The easiest way for you to do it would be to run this command in a console, modify the commands to use the fields you want, the *_id fields are required for your associations to work:
rails generate model user name:string email:string otherfield:integer
rails generate model check_in user_id:integer room_id:integer
rails generate model room number:integer
Note that these will also generate model files for you, since you already have these 3 model files it'll ask you if you want to overwrite them, or skip the files. You can skip them and it should be just fine. If you already had the migrations for part of the data in these models then you can just add the user_id and room_id fields to the check_in model by running this generator instead:
rails generate migration AddIdsToCheckIn user_id:integer room_id:integer
For rails 2.3.x replace rails generate with script/generate. Next you can inspect your migration(s) by opening the files up in db/migrate.rb and modify them there if you need to. Finally, run the migrations:
rake db:migrate
And it should work out for you. Note that I added a has_one, :through => relationship to User - this is so that you can do #user.room without having to make 3 chains: #user.check_in.room
You need to add the migrations yourself (or if you aren't live, you can modify an existing migration). Basically, you need to give the belongs_to side of the relationship a foreign key.
There is absolutely no reason to get flamed don't worry :) It seems here that you are trying to do a one to many association, but you're actually doing a many to many one.
If a user has one check in, it means that he/she has one room. So, you could just have :
user has_one room
room belongs to user
and room has a user_id.
Hope that helps :)
I have some problem trying to understand when building a rails app with several models and relation ships between them...
If I take a basic example like a model Group, a model User and a model Car
class Group < ActiveRecord::Base
has_many :users
end
class User < ActiveRecord::Base
belongs_to :group
has_many :cars
end
class Car < ActiveRecord::Base
belongs_to :user
end
Will those relation ship statements automatically create the following functions:
group.users
user.group
user.cars
car.user
It seems that we sometimes need to have to create "references" in migration (like adding a reference toward User in Car table) but is this always required ?
In this case, what is the difference of creating the migration and of adding the relationship statement in the models ? I sometimes have the feeling this is used for the same purpose.
Thanks a lot for your help,
Regards,
Luc
The association declarations are there for Rails only. You have to define the foreign keys (references) in the database, so that Rails can properly save the data.
Remember, despite all the magic, it's still backed by a relational database, so good practices there will pay off in the long run.