I have the following models:
class Restaurant < ApplicationRecord
has_one_attached :image
has_many :categories, through: :restaurant_category
end
class Category < ApplicationRecord
has_many :restaurants, through: :restaurant_category
end
class RestaurantCategory < ApplicationRecord
belongs_to :restaurant
belongs_to :category
end
I would query in one shot all the categories associated to a restaurant. SOmething like this:
a = Restaurant.find(1)
a.restaurant_category
But I have:
NoMethodError (undefined method `restaurant_category' for #<Restaurant:0x00007f5214ad2240>)
How can I solve it?
This:
class Restaurant < ApplicationRecord
has_one_attached :image
has_many :categories, through: :restaurant_category
end
... should look like this:
class Restaurant < ApplicationRecord
has_one_attached :image
has_many :restaurant_categories
has_many :categories, through: :restaurant_categories
end
Similarly, this:
class Category < ApplicationRecord
has_many :restaurants, through: :restaurant_category
end
... should look like this:
class Category < ApplicationRecord
has_many :restaurant_categories
has_many :restaurants, through: :restaurant_categories
end
Which you would use like:
restaurant_categories = Restaurant.find(1).categories
This is all explained in the has_many :through section of the Active Record Associations guide.
Related
Given these 4 Rails models:
class Apple < ActiveRecord::Base
has_one: ?
end
class Banana < ActiveRecord::Base
has_one: ?
end
class FruitMapping < ActiveRecord::Base
belongs_to :fruit, polymorphic: true
has_one :cart
end
class Cart < ActiveRecord::Base
end
How can I connect the has_one of the Apple/Banana to Cart, so that when I write apple.cart I will get the relevant Cart (through the mappings table)?
class Apple < ActiveRecord::Base
has_one :fruit_mapping, as: :fruit
end
class Cart < ActiveRecord::Base
has_many :fruit_mappigns
has_many :apples, through: :fruit_mappings, source: :fruit, source_type: 'Apple'
has_many :bananas, through: :fruit_mappings, source: :fruit, source_type: 'Banana'
end
Using the source and source_type options, you can define the polymorphic relationships. If using source and source_type are depricated in the Rails version you're using you can try
has_many :apples, through: :fruit_mappings, class_name: 'Apple', foreign_key: :fruit_id
I'm trying to create associations for three models in my Rails application. In the application a User can access courses which have videos. How would I model this?
This is what I currently have:
class User < ApplicationRecord
has_many :courses
has_many :videos, through: :courses
end
class Course < ApplicationRecord
belongs_to :user
has_many :videos
end
class Video < ApplicationRecord
belongs_to :course
belongs_to :user
end
Is this the correct way to model these associations for what I want the application to be able to achieve?
Normally, this would look something like:
class UserCourse < ApplicationRecord
belongs_to :user
belongs_to :course
end
class User < ApplicationRecord
has_many :user_courses
has_many :courses, through: :user_courses
has_many :videos, through: :courses
end
class Course < ApplicationRecord
has_many :user_courses
has_many :users, through: :user_courses
has_many :videos
end
class Video < ApplicationRecord
belongs_to :course
has_many :users, through: :course
end
That should let you do:
#user.courses
#user.videos
#course.users
#course.videos
#video.course
#video.users
(Assuming, of course, you've instantiated each of the above variables and you have associated records.)
I Have created simple rails apps and I got error "HasManyThroughCantAssociateThroughHasOneOrManyReflection" that shown in rails admin when I want to post an Image.
this my code:
can anyone Help me to solve it ?
class ProductInvest < ApplicationRecord
belongs_to :product
has_many :pictures, through: :product
end
class Product < ApplicationRecord
has_many :pictures
has_many :Product_invests
end
class Picture < ApplicationRecord
belongs_to :product
has_many :Product_invests, through: :product
end
Your associations aren't setup correctly. Try this instead:
class ProductInvest < ApplicationRecord
has_many :products
has_many :pictures, through: :products
end
class Product < ApplicationRecord
belongs_to :pictures
belongs_to :product_invests
end
class Picture < ApplicationRecord
has_many :products
has_many :product_invests, through: :products
end
You can get more information here: RubyGuides
I have an application with a business logic concerning products with multiple variants:
class Task < ApplicationRecord
belongs_to :variant
end
class Variant < ApplicationRecord
belongs_to :product
has_many :variant_option_values
has_many :option_values, through: :variant_option_values
has_many :prices
end
class Product < ApplicationRecord
has_many :product_option_types
has_many :option_types, through: :product_option_types
has_many :variants
end
class OptionValue < ApplicationRecord
belongs_to :option_type
end
class OptionType < ApplicationRecord
has_many :product_option_types
has_many :products, through: :product_option_types
has_many :option_values
end
class ProductOptionType < ApplicationRecord
belongs_to :product
belongs_to :option_type
end
class VariantOptionValue < ApplicationRecord
belongs_to :variant
belongs_to :option_value
end
The ERD looks like this:
Having a product product_1 how can I find its variants that have OptionValue instances option_value_1, option_value_2 and option_value_3? Note that the variant has to have all three option values at the same time and can have more than those three (but not necessarily).
option_values = [option_value_1, option_value_2, option_value_3]
Variant.include(product: [option_types: :option_values])
.where("option_values.id IN (?)", option_values.map(&:id))
.group("products.id")
.having("count(*) >= ?", option_values.size)
class Card < ApplicationRecord
has_one :card_rating
has_one :rating, through: :card_rating
end
class Rating < ApplicationRecord
has_many :card_ratings
has_many :cards, through: :card_ratings
end
class CardRating < ApplicationRecord
belongs_to :card
belongs_to :rating
end
I want to do something along the lines of the following:
c = card.card_rating.new
c << rating
But there doesn't seem to be any association going on at all, because already at the first statement I receive the following error:
undefined method `new' for nil:NilClass
You do not need a join table for a one to many relation:
class Card
belongs_to :rating
end
class Rating
has_many :cards
end
Rather you would use has_one :through in case the domain dictates that the relation is indirect.
class Student
belongs_to :school
has_one :headmaster, through: :school
end
class School
has_many :students
end
class Headmaster
belongs_to :school
has_many :students, through: :school
end