I am new to rails and have a very basic question.
While creating models, for ex. I have to store recipe and its steps. Now should i make recipe table, steps table and recipe_steps table or should i have recipe , steps table and in the model for recipe define has_many :steps?
Any help would be great.
Thanks a lot
You always need to have 3 tables in your database. As you said recipes steps and recipe_steps
Then you have two solutions with your models. The first one with 3 models:
class Recipe
has_many :recipe_steps
has_many :steps, through: :recipe_steps
end
class Step
has_many :recipe_steps
has_many :recipes, through: :recipe_steps
end
class RecipeStep
belongs_to :step
belongs_to :recipe
end
The second one with only two models:
class Recipe
has_and_belongs_to_many :steps
end
class Step
has_and_belongs_to_many :recipes
end
You will use the second solution if you don't want to manage data in the recipe_steps table. But if you want to add some informations in this table (price or quantity for example), you must use the first solution.
In all cases you must create the 3 tables.
You will find more information here: http://guides.rubyonrails.org/association_basics.html
I hope this help
Related
I am trying to make Rails-based application (and I'm just learning RoR as I go) and I stumbled upon this problem.
There are two models: Recipe and Item (food items). Recipe can have zero (we can create recipe before adding items) or many items. But a specific food item should not be bound to any recipe. That is why 'has_many' and 'belongs_to' won't work for me, as the latter does not fill this requirement.
If I was to do this without any framework, I would probably put an 'items' column in Recipe table, which would contain a list of item indices. But I have a hunch that this is not an appropriate way to do this in RoR since there are model associations in Rails.
Please, could someone give me an idea how to go about this?
I normally don't use has_and_belongs_to_many, but in your case it seems it might fit. You can use it like this:
class Recipe
has_and_belongs_to_many :items
end
class Item
has_and_belongs_to_many :recipes
end
You can also use has_many :through, but you would have to create a third table to join the Recipe and Item tables together.
class Recipe
has_many :item_recipes
has_many :items, through: :item_recipes
end
class ItemRecipes
belongs_to :recipe
belongs_to :item
end
class Item
has_many :item_recipes
has_many :recipes, through: :item_recipes
end
You can find more information here: Rails Associations
So currently i have in a app:
class Post < ApplicationRecord
belongs_to :category
end
and
class Category < ApplicationRecord
has_many :posts
end
which works fine as expected. However, i need to add multiple categories to a post . I thought about using has_many_and_belongs_to for each of them to acquire this but some trouble implementing this. It seems like a need to add an join table? If so, how would one look like with the setup shown above?
Any ideas?
I appreciate any input! Thanks in advance!
The table should be named categories_posts (categories comes first because of alphabetical sequence) and contain post_id and category_id integer columns (indexed, most probably). The it's as simple as:
class Post < ApplicationRecord
has_and_belongs_to_many :categories
end
class Category < ApplicationRecord
has_and_belongs_to_many :posts
end
You can create join table adding migration using:
rails g migration CreateJoinTableCategoryPost category post
Alternatively you can use has_many :through to have more control over a join table.
Advantages of using :through for many to many relationships
With has_many :through relationship you can have a model which will allow you to add validation, callbacks.
If you initially take some extra efforts to setup many to many relationship using through it can save a lot of time and headache in future
What if in future you want save the more information on join table like some custom sort, information about how the tables are associated which will not be allowed with has_and_belongs_to_many
Example
class Post < ApplicationRecord
has_many :categories, through: :post_categories
has_many :post_categories
end
class Category < ApplicationRecord
has_many :posts, through: :post_categories
has_many :post_categories
end
Adding relationship model with rails generator command
rails g model post_category category_id:integer post_id:integer custom:text
class PostCategory < ApplicationRecord
belongs_to :category
belongs_to :post
end
I have a user and project model created in Rails. I have to perform an association that will create an relationship which is described below:
1 User has many Projects
1 project has many Users
How can I go about creating an association for the same in Rails? I need some help on which type of association in rails will help me to achieve this.
You are describing a many-to-many relationship type. Rails allows you to create this relationship using has_many :through and has_and_belongs_to_many directives. You can learn the difference here.
Shortly, has_many :through allows you to add additional columns into the intermediate table, has_and_belongs_to_many doesn't. If you don't need to have additional attributes in the intermediate table than use has_and_belongs_to_many syntax. You can always change to has_many :through later.
class Project < ActiveRecord::Base
has_and_belongs_to_many :users
end
class User < ActiveRecord::Base
has_and_belongs_to_many :projects
end
You are basically trying to have a many-to-many relationship.
In Rails you can do this based on two association concept:
has_and_belongs_to_many (HABTM)
has_many :through
Note:
You should have HABTM if you just do not care about the way these two tables are joined (relationship model) and you do not want to have any logic/validation for your join data. It will just keep your foreign keys in a table and based on that data will be fetched.
You need has_many :through if you want to have an intermediate model in between Project and User which can be called as UserProject model. This way your association could look like as follows:
User Model:
has_many :user_projects
has_many :projects, through: :user_projects
Project Model:
has_many :user_projects
has_many :users, through: :user_projects
UserProject Model:
belongs_to :user
belongs_to :project
You can use has_and_belongs_to_many or has_many through.Here is the link I am providing which will help you to sort out difference between them and which one will be good for you.Here is the video tutorial for you association.ALso there is a good link link.In your case you need has and belongs to many
The best thing to do in this situation is ,
In your user.rb model file:
has_and_belongs_to_many :projects
and In your project.rb model file:
has_and_belongs_to_many :users
You may want too use many to many relationship between project and user. on top of that you may want to visit rails official guide which describes all of these relations in great detail.
http://guides.rubyonrails.org/association_basics.html
I am new to rails and been playing around with creating a web app for cooking, recipes, etc. to work through learning some new things. I have gotten a bit stuck on one particular aspect.
I have three tables set up to work together: lessons, preparations, and ingredients.
My models are set up like this:
class Lesson < ActiveRecord::Base
has_many :preparations
has_many :ingredients, through: :preparation
end
class Preparation < ActiveRecord::Base
belongs_to :lesson
has_many :ingredients
end
class Ingredient < ActiveRecord::Base
belongs_to :preparation
belongs_to :lessons, through: :preparation
end
In my lesson show view, I want to show the name of the ingredient. But I can only seem to get to the ingredient_id which is in the preparation table to link up with ingredients. So I can get the view to display a integer (the ingredient_id) but not the name. I've tried a bunch of things, but cannot seem to access the ingredients table.
Any help on how to get this configured correctly?
Thanks.
I'm trying to get the values from timestamps created in a lookup table. Let's say I've got Ingredients and Recipes, and a table called ingredients_recipes, with ingredient_id, recipe_id, and then the timestamps.
How can I get access to those timestamps? Basically, I need to know when a given ingredient was added to a recipe.
Thanks!
So you currently have something like this?
class ingredient << ActiveRecord::Base
has_and_belongs_to_many :recipes
.....
end
class recipe << ActiveRecord::Base
has_and_belongs_to_many :ingredients
....
end
And you want to get the dates they where added. The rails way to do this is by using a join model. (see http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html ) and many to many. particularly this line Choosing which way to build a many-to-many relationship is not always simple. If you need to work with the relationship model as its own entity, use has_many :through. Use has_and_belongs_to_many when working with legacy schemas or when you never work directly with the relationship itself.
So if you where to build a join model you would get something like below.
class ingredient << ActiveRecord::Base
has_many :mixtures
has_many :recipes , :through=> :mixtures
.....
end
class recipe << ActiveRecord::Base
has_many :mixtures
has_many :ingredients, :through=> :mixtures
....
end
class mixture << ActiveRecord::Base
belongs_to :recipe
belongs_to :ingredient
...
end
This way you can add attributes to the mixtures table, so you can find out when they where added, who added them etc...