I have models User, Tagging, Tag
User.rb
has_one :tagging
Tagging.rb
belongs_to :user
belongs_to :tag
Tag.rb
has_many :taggings
I want to scope the User based on the Tag's name. How to do it?
Currently, I know how to do the scope under one level association, for example:
scope :with_tag_id, -> (tag_id) {joins(:tagging).where(taggings: {tag_id: tag_id})}
But how to do more levels?
Try this
class User < ActiveRecord::Base
scope :by_tag_name, ->(tag_name) { joins(tagging: :tag).where("tags.name=?", tag_id, tag_name)
end
Related
I am trying to scope through an array of child records based on a value in one of the parent columns. I am trying to find all the ShoppingCartItems that belong to a Product with a category "Bundle."
I am trying to use acts_as_shopping_cart_gem
My Models.
User.rb
class User < ActiveRecord::Base
has_many :shopping_carts, dependent: :destroy
end
ShoppingCart.rb
class ShoppingCart < ActiveRecord::Base
acts_as_shopping_cart_using :shopping_cart_item
belongs_to :user
has_many :shopping_cart_items, dependent: :destroy
has_many :products, through: :shopping_cart_items
end
Product.rb
class Product < ActiveRecord::Base
has_many :shopping_cart_items, dependent: :destroy
end
ShoppingCartItem.rb
class ShoppingCartItem < ActiveRecord::Base
belongs_to :product, dependent: :destroy
scope :bundles, -> {
joins(:product).where('products.category = ?', 'Bundles') unless category.blank?
}
end
I am getting this error:
> undefined local variable or method `category' for
> #<Class:0x007fc0f40310d0>
Your problem is actually straight forward - there is nowhere you defined the category variable.
This is how I would do that (generalized scope):
scope :by_category, lambda { |category|
joins(:product).where(products: { category: category })
}
Note, there is no unless statement - if the category is not passed to scope, it will raise the ArgumentError.
Then use the scope for any category:
ShoppingCartItem.by_category('Bundles')
To prevent the blank category to be passed into scope, just make sure you pass the right string. You can create a dropdown of categories:
Product.pluck(:category)
or something similar, if it is a part of user interface.
The category field on your scope regards the ShoppingCartItem? If so, try self.category.blank?. If not, just remove the unless statement.
Maybe you need to add Category model and add this relation:
class Product < ActiveRecord::Base
has_many :shopping_cart_items, dependent: :destroy
belongs_to :category
end
I'm using filterrific gem, and need to scope the following.
I have 3 tables. And I would like scope the User model , that returns all university names.that all User belongs through Colleges. Colleges is the join table here. My models are as below (Rails 4.2):
class User < ActiveRecord::Base
has_many :colleges
has_many :universities, :through => colleges
# my current scope which is not working at all
scope :user_university, -> (user_university){joins(colleges: [ {university: :name}]).where("universities.name = ? ", user_university)}
end
class Colleges < ActiveRecord::Base
belongs_to :user
belongs_to :university
end
class University < ActiveRecord::Base
has_many :colleges
has_many :users, :through => colleges
end
I keep getting errors and I'm unsure how to scope a model through a join table.
Let try as this:
scope :user_university, -> (university_name) {
joins(colleges: :university).where(universities: {name: university_name})
}
I rename the parameter user_university to university_name btw, user_university is kind of confusing!
I have the following models set up:
class Location < ActiveRecord::Base
has_many :location_parking_locations
has_many :parking_locations, through: :location_parking_locations
end
class LocationParkingLocation < ActiveRecord::Base
belongs_to :location
belongs_to :parking_location
end
class ParkingLocation < ActiveRecord::Base
has_many :location_parking_locations
has_many :locations, through: :location_parking_locations
end
The LocationParkingLocation has an integer field called upvotes. I would like to create a 'by_votes' scope that I can add to a query to order the results by this upvotes field. Where and how do I define this scope, so that I can call it like this:
location.parking_locations.by_votes
I can't define it like this, because then it's not a valid method on parking_locations:
class LocationParkingLocation < ActiveRecord::Base
belongs_to :location
belongs_to :parking_location
scope :by_votes, -> { order("upvotes DESC") }
end
Should it be defined in the 'ParkingLocation' class? If so, how do I tell it that I want to order by a field on the location_parking_locations table?
I think you might be able to use merge here.
You can leave your scope in the LocationParkingLocation class, and the result would look like:
location.parking_locations.merge(LocationParkingLocation.by_votes)
I just read a little about it in this blog post.
rails 4.2
ruby 2.1
I have two very basic models (product and tag) with has_many association through another model (taggings).
I have another model (category) with one-to-many connection with the aforementioned model (product).
Question:
How to show in view the tag list of products with a specific product's category?
In other words: Is it possible to list all tags from a particular category of product?
Models:
class Product < ActiveRecord::Base
has_many :taggings
has_many :tags, through: :taggings
belongs_to :category, counter_cache: true
end
class Tag < ActiveRecord::Base
has_many :taggings
has_many :products, through: :taggings
end
class Tagging < ActiveRecord::Base
belongs_to :product
belongs_to :tag, counter_cache: :products_count
end
class Category < ActiveRecord::Base
has_many :products
end
Quickest way is category_object.products.map(&:tags).flatten . Can be improved. :)
category has many products and product has many tags. Mapping tags method on each product. Flatten to remove duplicates.
You can add a product_tags association to the Category class:
class Category < ActiveRecord::Base
has_many :products
has_many :product_tags, -> { uniq }, through: :products
end
When you access the product_tags association, Rails will use a SELECT DISTINCT query so you won't end up with duplicate tags and the DB will eliminate duplicates.
If the above doesn't feel natural for your model, then you can also use the following (assuming c is a Category instance):
Tag.joins(:products).where(products: { category: c})
The DB query will be very similar to the other example.
Users on my site each have one list, which consists of a different type of users. I'm using a has_many through relationship to do this as follows:
List.rb:
class List < ActiveRecord::Base
belongs_to :company
has_many :list_applicants
has_many :applicants, through: :list_applicants
end
Applicant.rb:
class Applicant < ActiveRecord::Base
has_many :list_applicants
has_many :lists, through: :list_applicants
end
ListApplicant.rb
class ListApplicant < ActiveRecord::Base
attr_accessible :applicant_id, :list_id
belongs_to :applicant
belongs_to :list
end
Company.rb:
class Company < ActiveRecord::Base
has_one :list
end
When a user adds another user to their list, I'd like to record the date the user is added so they can sort their list of users by date added. What is the best way to do this?
You can use the created_at field of the ListApplicant model if it has one. If not, you may add manually a similar field.
UPDATE:
You can access the field by specifying both applicant and list like this:
#applicant.list_applicants.where(list_id: #list.id).first.created_at