Rails Child id using parent id - ruby-on-rails

My issue is, when I am under the camper show page
Current Camper URL:
campers/1
and I go to click on to view the appointment it uses the camper_id for the appointment_id which is wrong so say if the camper_id is 1 it will use the appointment_id as 1 and actually the appointment id is 3, so then it says Couldn't find appointment with id of 1.
Table Header
<% #appointments.each do |app| %>
<%= link_to app.camper.camperName, appointment_path(#camper, #appointment) %>
Campers Controller Show Action
#appointments = #camper.appointments
Camper Model
has_many :appointments, dependent: :destroy
Appointment Model
belongs_to :camper
Shallow Nested Routes File
resources :customers, shallow: :true do
resources :campers do
resources :appointments do
resources :orders do
member do
patch :complete
end
end
end
end
end
Camper Controller
class CampersController < ApplicationController
before_action :set_camper, only: [:show, :edit, :update, :destroy]
# before_action :set_customer, only: [:index, :new, :edit, :create, :update]
load_and_authorize_resource
# GET /campers
# GET /campers.json
def index
#campers = #customer.campers
end
def list
query = params[:q].presence || ""
#campers = Camper.search(query, page: params[:page], per_page: 20, order: {created_at: :desc} )
end
# GET /campers/1
# GET /campers/1.js
def show
#appointments = #camper.appointments
respond_to do |format|
format.html
format.json
end
end
# GET /campers/new
def new
#customer = Customer.find(params[:customer_id])
#camper = #customer.campers.build
end
# GET /campers/1/edit
def edit
end
def page_name
"Campers"
end
# POST /campers
# POST /campers.json
def create
#camper = Camper.new(camper_params)
respond_to do |format|
if #camper.save
format.html { redirect_to camper_path(#camper), notice: 'Camper was successfully created.' }
format.json { render :show, status: :created, location: #camper }
else
format.html { render :new }
format.json { render json: #camper.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /campers/1
# PATCH/PUT /campers/1.json
def update
respond_to do |format|
if #camper.update(camper_params)
format.html { redirect_to camper_path(#camper), notice: 'Camper was successfully updated.' }
format.json { render :show, status: :ok, location: #camper }
else
format.html { render :edit }
format.json { render json: #camper.errors, status: :unprocessable_entity }
end
end
end
# DELETE /campers/1
# DELETE /campers/1.json
def destroy
#camper.destroy
respond_to do |format|
format.html { redirect_to root_path, notice: 'Camper was successfully deleted.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_camper
#camper = Camper.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def camper_params
params.require(:camper).permit(:order_id, :customer_id, :year, :manufacturer, :modelName, :camperClass, :vin, :mileage, :notes, :user_id)
end
end
Appointments Controller
class AppointmentsController < ApplicationController
before_action :set_appointment, only: [:show, :edit, :update, :destroy]
# GET /appointments
# GET /appointments.json
def index
#camper = Camper.find(params[:camper_id])
#appointments = #camper.appointments
end
# GET /appointments/1
# GET /appointments/1.json
def show
#orders = #appointment.orders
end
# GET /appointments/newå
def new
#camper = Camper.find(params[:camper_id])
#appointment = #camper.appointments.build
end
# GET /appointments/1/edit
def edit
end
# POST /appointments
# POST /appointments.json
def create
#appointment = Appointment.new(appointment_params)
respond_to do |format|
if #appointment.save
format.html { redirect_to appointment_path(#appointment), notice: 'Appointment was successfully created.' }
format.json { render :show, status: :created, location: #appointment }
else
format.html { render :new }
format.json { render json: #appointment.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /appointments/1
# PATCH/PUT /appointments/1.json
def update
respond_to do |format|
if #appointment.update(appointment_params)
format.html { redirect_to #appointment, notice: 'Appointment was successfully updated.' }
format.json { render :show, status: :ok, location: #appointment }
else
format.html { render :edit }
format.json { render json: #appointment.errors, status: :unprocessable_entity }
end
end
end
# DELETE /appointments/1
# DELETE /appointments/1.json
def destroy
#appointment.destroy
respond_to do |format|
format.html { redirect_to camper_appointments_path(#appointment), notice: 'Appointment was successfully deleted.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_appointment
#appointment = Appointment.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def appointment_params
params.require(:appointment).permit(:customer_id, :camper_id, :order_id, :title, :description, :date_in, :date_out)
end
end

appointment_path only takes a single appointment argument. Remove the #camper argument:
appointment_path(#appointment)

Related

how can i access boolean value to other controller in rails

i have ProjectSite model and ManagerRemark model related to many to one association. my MangerRemark model has boolean value true and false i want to access that boolean value to other controller view. please help. here is my code.i want to print decision boolean value next to each project site index list how can i do that? in other controller name new_manager_controller view
project_sites_controller.rb
class ProjectSitesController < ApplicationController
before_action :authenticate_user!
before_action :is_project_site?, except: [:show]
before_action :set_project_site, only: [:show, :edit, :update, :destroy]
# GET /project_sites
# GET /project_sites.json
def index
#project_sites = ProjectSite.all.order("created_at DESC")
end
# GET /project_sites/1
# GET /project_sites/1.json
def show
#manager_remark = ManagerRemark.new
#manager_remark.project_site_id = #project_site.id
end
# GET /project_sites/new
def new
#project_site = ProjectSite.new
end
# GET /project_sites/1/edit
def edit
end
# POST /project_sites
# POST /project_sites.json
def create
#project_site = ProjectSite.new(project_site_params)
respond_to do |format|
if #project_site.save
format.html { redirect_to #project_site, notice: 'Project site was successfully created.' }
format.json { render :show, status: :created, location: #project_site }
else
format.html { render :new }
format.json { render json: #project_site.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /project_sites/1
# PATCH/PUT /project_sites/1.json
def update
respond_to do |format|
if #project_site.update(project_site_params)
format.html { redirect_to #project_site, notice: 'Project site was successfully updated.' }
format.json { render :show, status: :ok, location: #project_site }
else
format.html { render :edit }
format.json { render json: #project_site.errors, status: :unprocessable_entity }
end
end
end
# DELETE /project_sites/1
# DELETE /project_sites/1.json
def destroy
#project_site.destroy
respond_to do |format|
format.html { redirect_to project_sites_url, notice: 'Project site was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_project_site
#project_site = ProjectSite.find(params[:id])
end
# Never trust parameters frmanager_level_twoom the scary internet, only allow the white list through.
def project_site_params
params.require(:project_site).permit(:name, :date, :file)
end
def is_project_site?
redirect_to root_path unless (current_user.role=='project_site')
end
end
This is how my manage remark controller looks.
Manager_Remarks_controller.rb
class ManagerRemarksController < ApplicationController
def create
#manager_remark = ManagerRemark.new(remark_params)
#manager_remark.project_site_id = params[:project_site_id]
#manager_remark.save
redirect_to project_site_path(#manager_remark.project_site)
end
def remark_params
params.require(:manager_remark).permit(:name, :remark, :decision)
end
end

One to Many To Many: One user has many store. One store has many products

I'm learning ROR. Trying to build this model: one user can have many store each store can have many product. I've been able to create store linking to its owner but I'm stuck at doing the same for product.
store.rb
class Store < ApplicationRecord
belongs_to :user
has_many :products, :foreign_key => :store_id
end
product.rb
class Product < ApplicationRecord
belongs_to :store
end
products_controller.rb
class ProductsController < ApplicationController
before_action :set_product, only: [:show, :edit, :update, :destroy]
# GET /products
# GET /products.json
def index
#products = Product.all
end
# GET /products/1
# GET /products/1.json
def show
end
# GET /products/new
def new
end
# GET /products/1/edit
def edit
end
# POST /products
# POST /products.json
def create
#product = Product.new(product_params)
respond_to do |format|
if #product.save
format.html { redirect_to #product, notice: 'Product was successfully created.' }
format.json { render :show, status: :created, location: #product }
else
format.html { render :new }
format.json { render json: #product.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /products/1
# PATCH/PUT /products/1.json
def update
respond_to do |format|
if #product.update(product_params)
format.html { redirect_to #product, notice: 'Product was successfully updated.' }
format.json { render :show, status: :ok, location: #product }
else
format.html { render :edit }
format.json { render json: #product.errors, status: :unprocessable_entity }
end
end
end
# DELETE /products/1
# DELETE /products/1.json
def destroy
#product.destroy
respond_to do |format|
format.html { redirect_to products_url, notice: 'Product was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_product
#product = Product.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def product_params
params.require(:product).permit(:product_name, :product_price, :product_description, :product_tag, :sku_code)
end
end
stores_controller.rb
class StoresController < ApplicationController
before_action :set_store, only: [:show, :edit, :update, :destroy]
# GET /stores
# GET /stores.json
def index
#stores = Store.all
end
# GET /stores/1
# GET /stores/1.json
def show
#products = Product.all
end
# GET /stores/new
def new
#store = Store.new
end
# GET /stores/1/edit
def edit
end
# POST /stores
# POST /stores.json
def create
#store = Store.new(store_params)
#store.user_id = current_user.id
respond_to do |format|
if #store.save
format.html { redirect_to #store, notice: 'Store was successfully created.' }
format.json { render :show, status: :created, location: #store }
else
format.html { render :new }
format.json { render json: #store.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /stores/1
# PATCH/PUT /stores/1.json
def update
respond_to do |format|
if #store.update(store_params)
format.html { redirect_to #store, notice: 'Store was successfully updated.' }
format.json { render :show, status: :ok, location: #store }
else
format.html { render :edit }
format.json { render json: #store.errors, status: :unprocessable_entity }
end
end
end
# DELETE /stores/1
# DELETE /stores/1.json
def destroy
#store.destroy
respond_to do |format|
format.html { redirect_to stores_url, notice: 'Store was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_store
#store = Store.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def store_params
params.require(:store).permit(:store_name, :store_description)
end
end
I expect when creating a product, it will get the store_id immediately. I'm keep getting "store must exist" message
From Rails 5, belongs_to requires the association object to be present. If your product object does not have a valid store_id (nil or inexistent store object), that product object will not be valid.
You can bypass this by allowing the association to be optional
class Product < ApplicationRecord
belongs_to :store, optional: true
end
Or, you should allow store_id as permitted parameter in your products_controller and pass it when you create a new product
# below code I assume that your store table has a column called 'store_name'
<%= form_for #product do |f| %>
<%= f.collection_select :store_id, current_user.stores, :id, :store_name, prompt: 'Please select the store of this product' %>
<%= f.submit %>
<% end %>

how do i calculate the end time of appointment when i know length of the service?

I have two models, Services and Appointments. A Service can have many appointments.
I have a nested form for users to book appointments.
How can I have the end time of the appointment automatically calculated? Understandably, I'd rather not rely on the user to enter an end time based on the length of the Service they have selected.
Currently my controller looks like this...
class AppointmentsController < ApplicationController
before_action :set_appointment, only: [:show, :edit, :update, :destroy]
before_action :load_services, only: [:new, :edit]
after_filter :end_calculate, only: [:create, :update]
[...]
# POST /appointments
# POST /appointments.json
def create
#appointment = Appointment.new(appointment_params)
respond_to do |format|
if #appointment.save
# redirect_to root_url
format.html { redirect_to #appointment, notice: 'Appointment was successfully created.' }
format.json { render :show, status: :created, location: #appointment }
else
format.html { render :new }
format.json { render json: #appointment.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /appointments/1
# PATCH/PUT /appointments/1.json
def update
respond_to do |format|
if #appointment.update(appointment_params)
format.html { redirect_to #appointment, notice: 'Appointment was successfully updated.' }
format.json { render :show, status: :ok, location: #appointment }
else
format.html { render :edit }
format.json { render json: #appointment.errors, status: :unprocessable_entity }
end
end
end
[...]
private
# Use callbacks to share common setup or constraints between actions.
def set_appointment
#appointment = Appointment.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def appointment_params
params.require(:appointment).permit(:start_time, :end_time, :note, :service_id)
end
def load_services
#services = Service.all.collect {|service| [ service.title, service.length, service.id] }
end
def end_calculate
#appointment.end_time = #appointment.start_time + #service.length.minutes
#appointment.end_time.save
end
end
So, after a discussion the solution is to remove the end_calculate method from controller, and to add end_time method to Appointment class:
def end_time
end_time = self.start_time + self.service.length.minutes
end

Rails 4: Incrementing Repeated items

want to increment repeated items on my shopping app
so when a users places an order and then wants to edit the order he can change the order quantities.
At the moment when i click on the quantity (i have set the quantity to 1) It goes to the order_itmes editing screen - it allows me to update the order but when i click submit get an error
NameError in OrderItemsController#update
#order_item = OrderItem.find(params[:id])
respond_to do |format|
if order_item.params[:quantity].to_i == 0 **<-----Error**
#order_item.destroy
format.html { redirect_to #order_item.order, notice: 'Item was deleted from your cart.' }
format.json { head :no_content }
parameters
{"utf8"=>"✓",
"_method"=>"patch",
"authenticity_token"=>"/8xRjbtusgdLV5SVQP55aUDccYdUzB9G23heTtEeNfk=",
"order_item"=>{"quantity"=>"2"},
"commit"=>"Update Order item",
"id"=>"68"}
order_items controller
class OrderItemsController < ApplicationController
before_action :set_order_item, only: [:show, :edit, :destroy]
before_action :load_order, only: [:create]
# GET /order_items/1/edit
def edit
end
# POST /order_items
# POST /order_items.json
def create
#order_item = #order.order_items.find_or_initialize_by_product_id(params[:product_id])
#order_item.quantity += 1
respond_to do |format|
if #order_item.save
format.html { redirect_to #order, notice: 'Successfully Added Product To Cart.' }
format.json { render action: 'show', status: :created, location: #order_item }
else
format.html { render action: 'new' }
format.json { render json: #order_item.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /order_items/1
# PATCH/PUT /order_items/1.json
def update
#order_item = OrderItem.find(params[:id])
respond_to do |format|
if order_item.params[:quantity].to_i == 0
#order_item.destroy
format.html { redirect_to #order_item.order, notice: 'Item was deleted from your cart.' }
format.json { head :no_content }
elsif #order_item.update(order_item_params)
format.html { redirect_to #order_item.order, notice: 'Successfully updated the order item.' }
else
format.html { render action: 'edit' }
format.json { render json: #order_item.errors, status: :unprocessable_entity }
end
end
end
# DELETE /order_items/1
# DELETE /order_items/1.json
def destroy
#order_item.destroy
respond_to do |format|
format.html { redirect_to #order_item.order }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_order_item
#order_item = OrderItem.find(params[:id])
end
def load_order
#order = Order.find_or_initialize_by_id(session[:order_id], status: "Unsubmitted", user_id: session[:user_id])
if #order.new_record?
#order.save!
session[:order_id] = #order.id
end
end
# Never trust parameters from the scary internet, only allow the white list through.
def order_item_params
params.require(:order_item).permit(:product_id, :order_id, :quantity)
end
end
order.controller
class OrdersController < ApplicationController
before_action :set_order, only: [:show, :edit, :update, :destroy, :confirm]
# GET /orders
# GET /orders.json
def index
#orders = Order.all
end
# GET /orders/1
# GET /orders/1.json
def show
end
# GET /orders/new
def new
#order = Order.new
end
# GET /orders/1/edit
def edit
end
# POST /orders
# POST /orders.json
def create
#order = Order.new(order_params)
respond_to do |format|
if #order.save
format.html { redirect_to #order, notice: 'Order was successfully created.' }
format.json { render action: 'show', status: :created, location: #order }
else
format.html { render action: 'new' }
format.json { render json: #order.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /orders/1
# PATCH/PUT /orders/1.json
def update
respond_to do |format|
if #order.update(order_params.merge(status: 'submitted'))
format.html { redirect_to confirm_order_path(#order), notice: 'Order was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #order.errors, status: :unprocessable_entity }
end
end
end
# DELETE /orders/1
# DELETE /orders/1.json
def destroy
#order.destroy
respond_to do |format|
format.html { redirect_to products_path }
format.json { head :no_content }
end
end
def confirm
end
private
# Use callbacks to share common setup or constraints between actions.
def set_order
#order = Order.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def order_params
params.require(:order).permit(:user_id, :status, :address_id)
end
end
order_item.rb
class OrderItem < ActiveRecord::Base
belongs_to :order
belongs_to :product
validates :order_id, :product_id, presence: true
validates :quantity, numericality: { only_integer: true, greater_than: 0 }
def subtotal
quantity * product.price
end
end
just seen it if order_item.params[:quantity].to_i == 0
should be if order_item_params[:quantity].to_i == 0

Rails 4: No double items in shopping app

building a shopping app but i don't want to show to listings of the same thing twice. I don't want it to show two listings for oranges. Instead I want it to show the quantity as 2.
I have changed the order_items_controller to show
#order_item = #order.order_items.find_or_initialize_by_product_id(params[:product_id])
#order_item.quantity += 1
get error undefined method `price' for nil:NilClass
tr>
<th>Order Total</th>
<td><%= print_price #order.total %></td> <- error
</tr>
<tr>
order_items.controller
class OrderItemsController < ApplicationController
before_action :set_order_item, only: [:show, :edit, :update, :destroy]
before_action :load_order, only: [:create]
# GET /order_items/1/edit
def edit
end
# POST /order_items
# POST /order_items.json
def create
#order_item = #order.order_items.find_or_initialize_by_product_id(params[:product_id])
respond_to do |format|
if #order_item.save
format.html { redirect_to #order, notice: 'Successfully Added Product To Cart.' }
format.json { render action: 'show', status: :created, location: #order_item }
else
format.html { render action: 'new' }
format.json { render json: #order_item.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /order_items/1
# PATCH/PUT /order_items/1.json
def update
respond_to do |format|
if #order_item.update(order_item_params)
format.html { redirect_to #order_item, notice: 'Order item was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #order_item.errors, status: :unprocessable_entity }
end
end
end
# DELETE /order_items/1
# DELETE /order_items/1.json
def destroy
#order_item.destroy
respond_to do |format|
format.html { redirect_to #order_item.order }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_order_item
#order_item = OrderItem.find(params[:id])
end
def load_order
#order = Order.find_or_initialize_by_id(session[:order_id], status: "Unsubmitted")
if #order.new_record?
#order.save!
session[:order_id] = #order.id
end
end
# Never trust parameters from the scary internet, only allow the white list through.
def order_item_params
params.require(:order_item).permit(:product_id, :order_id, :quantity)
end
end
orders.show.html
class OrderItemsController < ApplicationController
before_action :set_order_item, only: [:show, :edit, :update, :destroy]
before_action :load_order, only: [:create]
# GET /order_items/1/edit
def edit
end
# POST /order_items
# POST /order_items.json
def create
#order_item = #order.order_items.find_or_initialize_by_product_id(params[:product_id])
respond_to do |format|
if #order_item.save
format.html { redirect_to #order, notice: 'Successfully Added Product To Cart.' }
format.json { render action: 'show', status: :created, location: #order_item }
else
format.html { render action: 'new' }
format.json { render json: #order_item.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /order_items/1
# PATCH/PUT /order_items/1.json
def update
respond_to do |format|
if #order_item.update(order_item_params)
format.html { redirect_to #order_item, notice: 'Order item was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #order_item.errors, status: :unprocessable_entity }
end
end
end
# DELETE /order_items/1
# DELETE /order_items/1.json
def destroy
#order_item.destroy
respond_to do |format|
format.html { redirect_to #order_item.order }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_order_item
#order_item = OrderItem.find(params[:id])
end
def load_order
#order = Order.find_or_initialize_by_id(session[:order_id], status: "Unsubmitted")
if #order.new_record?
#order.save!
session[:order_id] = #order.id
end
end
# Never trust parameters from the scary internet, only allow the white list through.
def order_item_params
params.require(:order_item).permit(:product_id, :order_id, :quantity)
end
end
order.rb
class Order < ActiveRecord::Base
has_many :order_items, dependent: :destroy
def total
order_items.map(&:subtotal).sum
end
end
order_items.rb
class OrderItem < ActiveRecord::Base
belongs_to :order
belongs_to :product
validates :order_id, :product_id, presence: true
def subtotal
quantity * product.price
end
end
I have also created a table to add quantity
class AddDefaultQuantityToOrderItems < ActiveRecord::Migration
def change
change_column :order_items, :quantity, :integer, default: 0
end
end
The problem might be in your order model. You need 'self' to reference the current Order object. Change it to this
def total
self.order_items.map(&:subtotal).sum
end
In your create action for the order controller you need
#order = Order.find(<however you get the order id>)
you are trying to call a method on #order but you are not passing a value in the controller for that item as far as I can tell

Resources