I will go stand in the corner for an hour and hang my head in shame due to my poor naming conventions,
Seriously though cheers guys, and yeah please do some more episodes on Data and this stuff haha
That worked!! mmm ok i really need to consider my naming of tables in the future i think. Or make it clearer that a table is a join table haha
Thanks again Chris and Jacob for all your help!!
The join table you mention Chris is the
back_bar. Maybe I should have called it something else like
venue_products i was just trying to keep it with the terminology used in the app :)
Hoping this displays right, this is what my table is like (minus the date fields) basically this shows that have 3 products in Venue ID 1 and 1 product with Venue ID 2
id venue_id product_id price stock_level 1 1 5 0 NULL 2 1 1 0 NULL 3 2 1 0 NULL 4 1 4 0 NULL
Using this code below i can return a list of items in from the DB and display a list of products that are in a venue's back bar. This works. But i am sure there is a better way to do it.
def show # Look up Venue @venue = Venue.find(params[:venue_id]) if !@venue.nil? # Venue found look up back bar items @products_in_backbar = BackBar.select(:product_id).where(:venue_id => @venue.id) @products = Product.where(id: @products_in_backbar) else #Redirect to Venue page redirect_to venues_path end return end
Yeah, a product can be part of multiple bar bars, and a back bar can have more than 1 product.
I thought that having a back bar table would make things easier haha. The reason being is each product could have a different price per venue - yeah it's a crazy system i am working on, but fun lol
I think I understand why you're both saying I need a
back_bar_id on the
product table. And i think this is where the confusion is occurring, on my part.
The association I have is the
product_id on the
BackBar table, goes with the
id on the
Product table. so I guess the Product class 'has_many :back_bars' as thats where the association goes?
Maybe I am not explaining it right then.
Basically, this is the journey.
- A user finds a product, they first select the venue and then add it to the BackBar for that venue.
- This gets stored in the
back_barstable as detailed above. It stores the
What i am trying to do, is similar to the Articles issue i had originally. Where I am getting back a list of items that are associated to a
venue_id from the
back_bar table. This provides me with a
product_id with this I can get back the details of that product to display in a list in on the venue's back bar page.
This is the code i am now using and is working... but as with the articles method i am sure it can be simplified.
(im not sure how to do comments on here)
def show //Look up Venue @venue = Venue.find(params[:venue_id]) if !@venue.nil? //Venue found look up back bar items @products_in_backbar = BackBar.select(:product_id).where(:venue_id => @venue.id) @products = Product.where(id: @products_in_backbar) else //Redirect to Venues page redirect_to venues_path end return end
Yeah I got that there was a missing column in the DB but having the 'back_bar_id' on the products table makes no sense.
A backbar can have many products, but belongs to a venue. Thus the backbar references the venue and product as per my previous posts.
I tried to do the same as we did for articles
But it just doesn't want to work and I can't see why
This is the table for back bar. Basically I am adding a
product_id when a user adds a product to the back bar.
create_table "back_bars", force: :cascade do |t| t.integer "venue_id" t.integer "product_id" t.decimal "price", default: "0.0" t.integer "stock_level" t.integer "last_ordered_amount" t.datetime "last_ordered_at" t.boolean "active", default: false t.datetime "created_at", null: false t.datetime "updated_at", null: false t.index ["product_id"], name: "index_back_bars_on_product_id", using: :btree t.index ["venue_id"], name: "index_back_bars_on_venue_id", using: :btree end
It would seem thats not quite right, I am getting this error...
PG::UndefinedColumn: ERROR: column products.back_bar_id does not exist LINE 1: SELECT 1 AS one FROM "products" WHERE "products"."back_bar_... ^ : SELECT 1 AS one FROM "products" WHERE "products"."back_bar_id" = $1 LIMIT $2
Cheers Jacob the second one makes more sense as each venue can only have one backbar.
That's interesting that products doesn't need anything to associate it. Maybe I need to read up more of a few of these concepts.
I am trying to get this to include product details too, like we did above but for some reason i can't get it to work :/ could you see what i am missing please?
I am Getting a list the items in a backbar, which works fine, until i add in the
includes() bit to get the extra details. I really can't get my head around includes(). lol
@products = BackBar.where(:venue_id => @venue.id).includes(:product)
@products = BackBar.where(:venue_id => @venue.id) returns a list of items which are in the BackBar table, in there are 2 fields which are referenced
product_id -- Returns
id: 1, venue_id: 1, product_id: 5
class BackBar < ApplicationRecord belongs_to :product has_many :venues end
class Product < ApplicationRecord has_many :back_bars end
class Venue < ApplicationRecord belongs_to :back_bar end
does it have to be "Products_count"?
So i would set up the counter cache like so?
belongs_to :category counter_cache: true
The i could use the
Category.where("products_count > 0") query. The i assume with those results i could get the products using 'includes(:product)' like we did before?
That's a typo on here where I typed it out. In the code it says
.products.any. Updated the post, thanks for spotting
I want to know if there is a better way to get a list of categories which only have products.
I have tried to do
@categories = Category.where(category_type: 'product').order(name: :asc).products.any but that seems to error and i am not sure why.
has_many :products and my
belongs_to :category so i assumed this would work.
In my controller i am am getting a list of categories.
def index @categories = Category.where(category_type: 'product').order(name: :asc) end
Then populating them on the page like as per below... now this work but its dirty and ends up with loads of calls to the DB which i don't personally like haha.
<% @categories.each do |category| %> <% if category.products.any? %> <div class="pad1 list-row"> <div class="space-left4 pad1x row-details"> <!-- Details --> <div class="details-name"><%= category.name %></div> <div class="details-sub">Products: <%= category.products.count %></div> </div> <div class="row-actions"></div> </div> <% end %> <% end %>
Yeah haha I am getting there, can't believe how far i have come! Not to mention how i understand Rails better in 6 months compared to 8 years coding .NET!
would this be the same if i wanted to get a variants volume type?
Would i need to add
, through: : products on the
has_one :volume_types in the
I have the following...
product has_many :product_variants, dependent: :destroy
product_variant belongs_to :product has_one :volume_types # table has: volume_type_id
Volume Type Model
volume_type belongs_to :product_variant #table: volume_types #t.string "short_name"
Chris, can I just have a direct link to your brain, please? haha
Hi again :)
I would like to know how to get my routes how i want them haha as we all do :) Basically i want to get the edit variant URL to be like
I have used the code below to get my routes, however its not doing what i thought it might.
# Products routing resources :products do resource :variants, module: :products end
This gives me the following routes...
product_variants POST /products/:product_id/variants(.:format) products/variants#create new_product_variants GET /products/:product_id/variants/new(.:format) products/variants#new edit_product_variants GET /products/:product_id/variants/edit(.:format) products/variants#edit GET /products/:product_id/variants(.:format) products/variants#show PATCH /products/:product_id/variants(.:format) products/variants#update PUT /products/:product_id/variants(.:format) products/variants#update DELETE /products/:product_id/variants(.:format) products/variants#destroy