Unable to nest JSON Rails - ruby-on-rails

I'm having trouble nesting my objects that have a has_many through relationships via rails.
My models look like this:
class SessionDetail < ActiveRecord::Base
has_many :session_enrollments, dependent: :destroy
has_many :customers, through: :session_enrollments
end
class SessionEnrollment < ActiveRecord::Base
belongs_to :customers //column name is "customers_id"
belongs_to :session_details //column name is "sessiondetails_id"
end
class Customer < ActiveRecord::Base
has_many :session_enrollments
has_many :session_details, through: :session_enrollments
end
I'm trying to nest a json object to return an array of session details, with a sub array of customers and a subarray (one object) of session_enrollments
My controller current looks like this:
def return_trainers_sessions
#trainer_requests = SessionDetail.where(trainers_id: params[:trainers_id], state: "PENDING")
unless (!#trainer_requests.any?)
respond_to do |format|
msg = {:status => "SUCCESS", :messages => "Requests Found", :requests => #trainer_requests.as_json(:includes => {:customers => {:include =>:session_enrollments}})}
format.json { render :json => msg } # don't do msg.to_json
end
I've also tried making a class method, but am only able to get as far as nesting the customers.
I end up returning no customers or session_enrollments, so my json just looks like I never added the includes to the right hand of .as_json

Watch your pluralization.
class SessionDetail < ActiveRecord::Base
has_many :session_enrollments, dependent: :destroy
has_many :customers, through: :session_enrollments
end
# a session enrollment belongs to a single customer, and a single session detail. Similarly
# the foreign key fields should be singular, customer_id, session_detail_id
class SessionEnrollment < ActiveRecord::Base
belongs_to :customer
belongs_to :session_detail
end
class Customer < ActiveRecord::Base
has_many :session_enrollments
has_many :session_details, through: :session_enrollments
end

Related

How to apply association rules

I'm confusing about association.
I tried to write code below but rails was returned me "undefined method `subs'".
def show
#product = Product.find(params[:id])
#materials = #product.materials.subs
respond_to do |format|
format.json { render json: [ #product,#materials ]}
end
end
I want Product model relates to Sub model and I get Sub model record.
If someone knows about this problem to solve please tell me.
class Product < ActiveRecord::Base
has_many :product_materials
has_many :materials, :through => :product_materials
end
class ProductMaterial < ActiveRecord::Base
belongs_to :product
belongs_to :material
end
class Material < ActiveRecord::Base
has_many :product_materials
has_many :products, :through => :product_materials
has_many :material_subs
has_many :subs, :through => :material_subs
end
class MaterialSub < ActiveRecord::Base
belongs_to :material
belongs_to :sub
end
class Sub < ActiveRecord::Base
has_many :material_subs
has_many :materials, :through => :material_subs
end
#product.materials is an array and you cannot chain a association on an array
#product = Product.includes(materials: :subs).find(params[:id])
#materials = #product.materials.flat_map(&:subs)
this will loop over the materials and will return subs for each material

How to use build method with a has_many :through association

My Models:
class Vip < ActiveRecord::Base
belongs_to :organization
has_many :events
has_many :organizations, :through => :events
end
class Organization < ActiveRecord::Base
belongs_to :user
has_many :events
has_many :vips, :through => :events
end
class Event < ActiveRecord::Base
belongs_to :organization
belongs_to :vip
end
My vips Controller:
def create
#organization = Organization.find(params[:organization_id])
#vip = #organization.vips.build(vip_params)
if #vip.save
redirect_to organization_path(#organization)
else
render 'new'
end
end
def vip_params
params.require(:vip).permit(:name, :about, :organization_id)
end
Before I started using the has_many :through associations, the build method would automatically add the foreign key to the new vip. So my vips table would have the organization_id column populated. Since using the has_many associations, the organization_id column is being left NULL on 'vip#create'.
Is there a reason that build wouldn't work the same way anymore with my new associations?

Rails has_many_belongs_to, has_many :through

I have 3 Models: Place, User, Reviews. Place and Users related with has_many_belongs_to - for favorites, and has_many :through - for reviews.
I want to insert to favorites some place, but this place inserted to reviews table, what is wrong?
Or create model Favorites?
class Place < ActiveRecord::Base
has_and_belongs_to_many :users
has_many :reviews
has_many :users, through: :reviews
end
class User < ActiveRecord::Base
has_and_belongs_to_many :places
has_many :reviews
has_many :places, through: :reviews
end
class Review < ActiveRecord::Base
belongs_to :user
belongs_to :place
end
class FavoritesController < ApplicationController
def add_favorites
if User.first.places.push(Place.find(params[:place_id]))
render json: {desc:true, status:0, error:nil}
else
render json: {desc:false, status:1, error: "Problem insert to table places_users"}
end
end
Have you try having different names for the associations? Right now both your favorites and reviewed places are called the same.
Try something like:
class User < ActiveRecord::Base
has_and_belongs_to_many :favorite_places
has_many :reviews
has_many :reviewed_places, through: :reviews
end
And for the controller:
User.first.favorite_places.push(Place.find(params[:place_id]))
You could always use active record serializers to store a array of favorites ids in the User model.
class User < ActiveRecord::Base
serialize :favorites
end
user = User.create(favorites: [1, 4, 8, 9])

complex query... how to join many classes in rails?

I have the following associations:
class Venue < ActiveRecord::Base
has_many :sales
end
class Sale < ActiveRecord::Base
has_many :sale_lines
has_many :beverages, through: :sale_lines
end
class SaleLine < ActiveRecord::Base
belongs_to :sale
belongs_to :beverage
end
class Beverage < ActiveRecord::Base
has_many :sale_lines
has_many :sales, through: :sale_lines
has_many :recipes
has_many :products, through: :recipes
end
class Recipe < ActiveRecord::Base
belongs_to :beverage
belongs_to :product
end
class Product < ActiveRecord::Base
has_many :recipes
has_many :beverages, through: :recipes
end
I wan't to see the quantity of products sold by each venue, so basically I have to multiply the recipe.quantity by the sale_line.quantity of an specific product.
I would like to call #venue.calc_sales(product) to get the quantity sold of product.
Inside the class Venue I am trying to calculating it by:
class Venue < ActiveRecord::Base
has_many :sales
def calc_sales(product)
sales.joins(:sale_lines, :beverages, :recipes).where('recipes.product_id = ?', product.id).sum('sale_lines.quantity * recipe.quantity')
end
end
However, I can't access the recipes in that way.
Any idea on how to achieve it?
For the joins, you have to use a Hash to join a already-joined table. It's hard to explain, but here are some examples:
Venue.joins(:sales, :beverages) : This implies that the relations :sales and :beverages are declared on the Venue model.
Venue.joins(:sales => :beverages) : This implies that the relation :sales exists on the Venue model, and the relation :beverages exists on the Sale model.
Consider this:
Venue
has_one :sale
Venue.joins(:sales) : This would not work, you have to use the exact same name as the relation between the Venue model & Sale model.
Venue.joins(:sale) : This would work because you used the same name of the relation.
Attention: You have to use the pluralized name in the where clause:
Venue.joins(:sale).where(:sales => { :id => sale.id })
^^ ^^ # See the plural
In your case, you can do something like this:
sales.joins(:sale_lines => { :beverage => :recipes })
.where(:recipes => { :product_id => product.id })
.sum('sale_lines.quantity * recipes.quantity')

Connecting tables to shopping cart

Connecting tables to shopping cart
I have three models and three database tables that I want to connect to one cart, I'm new in rails and have some problem to do this.
My initial idea was
Create model called Service as a parent of models Adverts, Package_of_products, and Subscriptions. And then connect it to cart by Line_item
Already know that I am doing something wrong
Each time when trying add one of my services to Line_items I getting message
ActiveRecord::RecordNotFound in LineItemsController#create
Couldn't find Service without an ID
app/controllers/line_items_controller.rb:44:in `create'
Already I have
def create
#cart = current_cart
service = Service.find(params[:service_id])
#line_item = #cart.line_items.build(:service => service)
respond_to do |format|
if #line_item.save
format.html { redirect_to(#line_item.cart, :notice => 'Line item was successfully created.')
end
I have 4 databas and models my Line_items
class LineItem < ActiveRecord::Base
belongs_to :service
belongs_to :cart
end
Cart
class Cart < ActiveRecord::Base
has_many :line_items, :dependent => :destroy
has_many :services,
has_many :adverts, :through => :services
has_many :package_of_products, :through => :services
has_many :subscriptions,:through => :services
Advert
class Advert < ActiveRecord::Base
belongs_to :service
end
Subscriptions
class Subscription < ActiveRecord::Base
belongs_to :service
end
Package_of_products
class PackageOfProduct < ActiveRecord::Base
belongs_to :service
end
ok, first the association name is belongs_to instead of belong_to, so please correct that misprint.
and then i think you need smth like this:
class Cart < ActiveRecord ::Base
has_many :line_items, :dependant => destroy
has_many :ads, :through => :line_items
has_many :products, :through => :line_items
has_many :services, :through => :line_items
end
check the has_many :through association here

Resources