I'm trying to make a product cart.
I want to be able choose the quantity of product when i add the product to cart.
This is LineItemsController
class LineItemsController < ApplicationController
include CurrentCart
before_action :set_line_item, only: [:show, :edit, :update, :destroy]
before_action :set_cart, only: [:create]
def index
#line_items = LineItem.all
end
def show
end
def new
#line_item = LineItem.new
end
def edit
end
def create
product = Product.find(params[:product_id])
#line_item = #cart.add_product(product)
#line_item.quantity = params['q'].to_i
if #line_item.save
redirect_to #line_item.cart, notice: 'Item added to cart.'
else
render :new
end
end
def update
if #line_item.update(line_item_params)
redirect_to #line_item, notice: 'Line item was successfully updated.'
else
render :edit
end
end
def destroy
#cart = Cart.find(session[:cart_id])
#line_item.destroy
redirect_to cart_path(#cart), notice: 'Item successfully removed.'
end
private
def set_line_item
#line_item = LineItem.find(params[:id])
end
def line_item_params
params.require(:line_item).permit(:product_id, :quantity)
end
end
This is view/line_item/_form.html.erb
<%= simple_form_for(#line_item) do |f| %>
<%= f.error_notification %>
<div class="form-inputs">
<%= f.association :product %>
<%= f.association :cart %>
</div>
<div class="form-actions">
<%= f.button :submit %>
</div>
<% end %>
This is view/product/show.html.erb
<% content_for :body_class, 'bg-light' %>
<section class="section instrument-show">
<div class="columns">
<div class="column is-8">
<%= render 'shared/breadcrumb', category: #product.category %>
<h1 class="title is-2"><%= #product.title %></h1>
<!--ul class="pv1">
<%# if #product.brand? %>
<li class="inline-block pr3"><%#= #product.brand %></li-->
<%# end %>
<!--li class="inline-block pr3"><%#= #product.model %></li-->
<%# if #product.condition? %>
<!--li class="inline-block pr3"><%#= #product.condition %></li>
<%# end %>
</ul-->
<div class="feature-image">
<%= image_tag(#product.image_url(:default).to_s) %>
</div>
<div class="content pa4 mt3 bg-white border-radius-3">
<h3 class="subtitle is-4">Description</h3>
<%= #product.description %>
<h3 class="subtitle is-4 pt5">Product Specs</h3>
<table class="table is-narrow">
<% if #product.category.present? %>
<tr>
<td class="has-text-weight-bold">Category:</td>
<td><%= link_to #product.category.name, #product.category %></td>
</tr>
<% end %>
<%# if #product.finish %>
<tr>
<td class="has-text-weight-bold">Finish:</td>
<td><%#= #product.finish %></td>
</tr>
<%# end %>
<tr>
<td class="has-text-weight-bold">Model:</td>
<td><%#= #product.model %></td>
</tr>
</table>
</div>
</div>
<div class="column is-3 is-offset-1">
<div class="bg-white pa4 border-radius-3">
<h4 class="title is-5 has-text-centered"><%= number_to_currency(#product.price) %></h4>
<p class="has-text-centered mb4">Sold by <%#= #product.user.name %></p>
<form>
<input type="number" name="q" min="1" max="50" step="1" class="input label">
</form>
<%= button_to 'Add to cart', line_items_path(product_id: #product), class: 'button is-warning add-to-cart' %>
</div>
</div>
</div>
<% if user_signed_in? && current_user.admin? %>
<%= link_to 'Edit', edit_admin_product_path(#product), class: 'button' %>
<% end %>
</section>
Now in this string #line_item.quantity = params['q'].to_i from
<form>
<input type="number" name="q" min="1" max="50" step="1" class="input label">
</form>
i'm getting "nil" and i desperately don't now what should i do to get actual number.
P.S. This is view/line_items/new.html.erb
<h1>New Line Item</h1>
<%= render 'form', line_item: #line_item %>
<%= link_to 'Back', line_items_path %>
new.html.erb is to enter your data and if you submit, the data will flow to create method inside your controller, meanwhile show is just to show the data, and you cannot input form inside show,
my suggestion try to put q part of new.html.erb, and put it inside simple_form_for tag
since it is number, you can use number_field rails tag helper as sample below, with name :q and range between 1 .. 50 with step 1, below is the sample probably can help your problem
when you submit from new.html.erb, you will receive params[:q] as part of parameters and save it with create method
<%= simple_form_for(#line_item) do |f| %>
<%= f.error_notification %>
<%= number_field(:q, in: 1.0..50.0, step: 1) %>
<div class="form-inputs">
<%= f.association :product %>
<%= f.association :cart %>
</div>
<div class="form-actions">
<%= f.button :submit %>
</div>
<% end %>
Related
I have a problem with a form in rails. I'm not able to show input error.
For example if I don't give in input the date (that's not optional), record isn't saved, but form does show anything.
This is my code:
FORM
_form.html.erb
<div class ="container">
<%= puts "Trip is nil: #{#trip.nil?}" %>
<%= form_with(model: trip) do |f| %>
<% if trip.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(trip.errors.count, "error") %> prohibited this book from being saved:</h2>
<ul>
<% trip.errors.full_messages.each do |error| %>
<li><%= error %></li>
<% puts "Error: #{error}" %>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :price %>
<%= f.text_field :price %>
</div>
<div class="field">
<%= f.label :date %>
<%= date_select :date, start_year: Date.current.year %>
</div>
<div class="field">
<%= f.label :Departure_time %>
<%= f.text_field :deptime %>
</div>
<div class="field">
<%= f.label :Arrival_time %>
<%= f.text_field :arrtime %>
</div>
<div class="field">
<%= f.label :From%>
<%= f.select :from_id, #places_arr %>
</div>
<div class="field">
<%= f.label :To%>
<%= f.select :to_id, #places_arr %>
</div>
<%= link_to 'Non trovi il posto che cerchi? Aggiungilo', new_place_path %>
<div class="field">
<%= f.label :vehicle %>
<%= f.select :vehicle_id, #vehicles_arr %>
</div>
<%= link_to 'Vuoi aggiungere un mezzo? Clicca qui', new_vehicle_path %>
<br/>
<div class="btn btn-primary">
<%= f.button :submit %>
</div>
<% end %>
</div>
_form it's a partial called by "new" template
<h1>New Trip</h1>
<%= puts "Trip in view: #{#trip}" %>
<%= render 'form', trip: #trip %>
<%= link_to 'Back', trips_path %>
This are the last lines of output of terminal when "submit" is pushed:
Trip in view: #<Trip:0x00007f61e4c4a548>
Trip is nil: false
Error: Date can't be blank
Rendered trips/_form.html.erb (Duration: 5.3ms | Allocations: 2831)
Rendered trips/new.html.erb within layouts/application (Duration: 6.1ms | Allocations: 3070)
[Webpacker] Everything's up-to-date. Nothing to do
Rendered layouts/_flash.html.erb (Duration: 0.0ms | Allocations: 11)
Completed 200 OK in 41ms (Views: 21.4ms | ActiveRecord: 3.6ms | Allocations: 21083)
You can see that if there's an error, lines within "if trip.errors.any?" (in form) are executed, in fact error on terminal are printed, but in html page errors don't appear.
Can someone help me?
For completness I also add controller code:
# GET /trips/new
def new
#places = Place.all
#places_arr = []
for i in (0...#places.length())
#places_el = [#places[i].name,#places[i].id]
#places_arr.push(#places_el)
end
#vehicles = Vehicle.all
#vehicles_arr = []
for i in (0...#vehicles.length())
#vehicles_el = [#vehicles[i].marca + " " + #vehicles[i].modello, #vehicles[i].id]
#vehicles_arr.push(#vehicles_el)
end
#trip = Trip.new
#parole = ["ciao","mi","chiamo","Gesualdo"]
##parole = []
end
# POST /trips or /trips.json
def create
#places = Place.all
#places_arr = []
for i in (0...#places.length())
#places_el = [#places[i].name,#places[i].id]
#places_arr.push(#places_el)
end
#vehicles = Vehicle.all
#vehicles_arr = []
for i in (0...#vehicles.length())
#vehicles_el = [#vehicles[i].marca + " " + #vehicles[i].modello, #vehicles[i].id]
#vehicles_arr.push(#vehicles_el)
end
#trip = Trip.new(trip_params)
puts "Nullo? #{#trip.nil?}"
if #trip.save
flash[:success] = "Trip successfully saved"
redirect_to #trip
else
render :new
end
#end
end
I am trying to add a devise login to another page but everytime I hit the submit button it redirects to to the main devise login page. I have tried using f.submit along with
<%= button_tag(type: 'submit') do %>
<span>GO</span><i class="fa fa-check"></i>
<% end %>
below is the full html
<div class="box">
<div class="title">LOGIN</div>
<%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
<div class="input">
<label for="name">Email</label>
<%= f.email_field :email, autofocus: true, autocomplete: "email", name: "name", id: "name"%>
<span class="spin"></span>
</div>
<div class="input">
<label for="pass">Password</label>
<%= f.password_field :password, autocomplete: "current-password", name: "pass", id: "pass" %>
<span class="spin"></span>
</div>
<div class="button login">
<%= button_tag(type: 'submit') do %>
<span>GO</span><i class="fa fa-check"></i>
<% end %>
</div>
<%- if devise_mapping.recoverable? && controller_name != 'passwords' && controller_name != 'registrations' %>
<%= link_to "Forgot your password?", new_password_path(resource_name), class: "pass-forgot" %>
<% end %>
<% end %>
</div>
Application_helper.rb
module ApplicationHelper
def resource_name
:user
end
def resource_class
User
end
def resource
#resource ||= User.new
end
def devise_mapping
#devise_mapping ||= Devise.mappings[:user]
end
end
The signup works fine but if a error is present it also redirects to the devise page. I have followed a couple tutorials on this but can not find a solution.
I have found a solution. To solve to issue all I had to do was remove the name: from the form fields.
Ive looked at atleast 8 other forums with the same title and none of the ones read helped me at all!
So im using a partial to render a form to a edit.html.erb page and a new.html.erb page. My controller page works except for the edit page!
Here is my code for my controller page :
class ProfilesController < ApplicationController
def new
# form where a user can fill out their own profile.
#user = User.find( params[:user_id] )
#profile = Profile.new
end
def create
#user = User.find( params[:user_id] )
#profile = #user.build_profile(profile_params)
if #profile.save
flash[:success] = "Profile Updated!"
redirect_to user_path( params[:user_id] )
else
render action: :new
end
end
def edit
#user = User.find( params[:id] )
#profile = #user.profile
end
private
def profile_params
params.require(:profile).permit(:first_name, :last_name, :job_title, :phone_number, :contact_email, :description)
end
end
my edit.html.erb page:
<div class="row">
<div class="col-md-6 col-md-offset-3">
<h1 class="text-center">Edit Your Profile</h1>
<p class="text-center">Be a part of the Dev Match community and fill out your profile!</p>
<div class="well">
<%= render 'form' %>
</div>
</div>
</div>
my new.html.erb page:
<div class="row">
<div class="col-md-6 col-md-offset-3">
<h1 class="text-center">Create Your Profile</h1>
<p class="text-center">Be a part of the Dev Match community and fill out your profile!</p>
<div class="well">
<%= render 'form' %>
</div>
</div>
</div>
and _form.html.erb:
<%=form_for (#profile) , url: user_profile_path do |f| %>
<div class="form-group">
<%= f.label :first_name %>
<%= f.text_field :first_name, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :last_name %>
<%= f.text_field :last_name, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :job_title %>
<%= f.select :job_title, ['Developer', 'Entrepreneur', 'Investor'], {}, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :phone_number %>
<%= f.text_field :phone_number, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :contact_email %>
<%= f.text_field :contact_email, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :description %>
<%= f.text_area :description, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.submit "Update Profile", class: 'btn btn-primary' %>
</div>
<% end %>
You change your code into this:
def edit
#user = User.find(params[:user_id])
#profile = #user.profile
end
#user is null because the id does not exist in DB.
If you create a new instance of User in the action new you can use the same object in the action create without use the method User.find
As improvement, try to add before_action in your controller.
class ProfilesController < ApplicationController
before_action :prepare_model, except: [:new, :create]
def new
# form where a user can fill out their own profile.
#user = User.new
#profile = Profile.new
end
def create
#profile = #user.build_profile(profile_params)
if #profile.save
flash[:success] = "Profile Updated!"
redirect_to user_path( params[:user_id] )
else
render action: :new
end
end
def edit
#profile = #user.profile
end
private
def prepare_model
#user = User.find(params[:user_id])
raise ActiveRecord::RecordNotFound if #user.nil?
end
def profile_params
params.require(:profile).permit(:first_name, :last_name, :job_title, :phone_number, :contact_email, :description)
end
end
I have a form called cattle finances, in this form, i use collection select to input the batch number, i have other form columns shown in the _form.html.erb code below
<%= simple_form_for #cattle_finance, remote: true do |f| %>
<% if #cattle_finance.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#cattle_finance.errors.count, "error") %> prohibited this cattle_finance from being saved:</h2>
<ul>
<% #cattle_finance.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<br>
<%= f.collection_select :batch_number, CattleList.all, :batch_number, :batch_number, :prompt => "please select Batch Number" %></br>
<%= f.input :total_litres_of_batch, as: :integer %>
<%= f.input :total_income, as: :integer %>
<%= f.input :gross_income, as: :integer %>
<%= f.input :total_expenses, as: :integer %>
<%= f.input :net_income, as: :integer %>
<%= f.input :date, as: :date %>
<%= f.button :submit %>
<% end %>
My index.html.erb code is
<div class="row">
<div class="col-md-5 col-md-offset-1">
<h2>Cattle Finances</h2>
</div>
<div class"btn-group menu2" align = right>
<%= link_to raw("<span class=''></span> Creditors"), cattle_creditors_path, :class=>"btn btn-default" %>
<%= link_to raw("<span class=''></span> Debtors"), cattle_debtors_path, :class=>"btn btn-default" %>
<%= link_to raw("<span class=''></span> Cattle"), cattles_path, :class=>"btn btn-default" %>
<%= link_to "Home", root_path, :class=>"btn btn-default" unless current_page?(root_url) %>
</div>
<div class="col-md-2 col-md-offset-4">
<%= link_to new_cattle_finance_path, remote: true do %>
<button class="btn btn-default">New</button>
<% end %>
</div>
</div>
<div class="row">
<div class="col-md-6 col-md-offset-2" id="cattle_finance-form" style="display:none;"></div>
</div>
<div class="row">
<div class="" id="cattle_finances"><%= render #cattle_finances %></div>
</div>
So what is need help with is the way in which i can select a particular batch_number and automatically all other fields are populated, or picked from the database from the corresponding database tables and filled in respectively. Any help his highly appreciated coz am stuck, although
i know what i want to do, I have no idea of how i can start.
*********SOLUTION********
<%= f.hidden_field :property_id, :value => #property.id %>
the hidden field was not properly assigned to f which failed to pass to the controller. Thank You Steve Klein
I am currently working on a website where people can post and review properties.
I'm running Ruby 2.2.0 and Rails 4.2.3.
I currently have a property class that also displays reviews belonging to that class. There is also a simple create view interface rendered through a partial form. The Review Create method needs
description
user_id
property_id
The create method properly receives through the params the :description and :user_id however the property_id is not being properly assigned. The validations in review.rb accepts the description and user_id but not the property_id.
Property.find_by_id(params[:id]).id
In the _review_form.html.erb
#property.id
In the show.html.erb
both correctly return the id of the current property in the views.
Can Anyone see what I'm doing wrong? Any help would be greatly appreciated.
class Review < ActiveRecord::Base
belongs_to :property
belongs_to :user
default_scope -> { order(created_at: :desc) }
validates :user_id, presence: true
validates :property_id, presence: true
end
class ReviewsController < ApplicationController
before_action :logged_in_user, only: [:create, :destroy]
def create
#Errors out #review = Review.build(review_params) Review.build method does not exist
##review = current_user.reviews.build(review_params)
#review = Review.new(review_params)
#review.user_id = current_user.id
#review.save
if #review.save
flash[:success] = "Review created!"
else
flash[:failure] = "Try Again"
end
redirect_to :back
end
def destroy
end
private
def review_params
params.require(:review).permit(:description, :property_id)
end
end
class CreateReviews < ActiveRecord::Migration
def change
create_table :reviews do |t|
t.text :description
t.references :property, index: true, foreign_key: true
t.references :user, index: true, foreign_key: true
t.timestamps null: false
end
add_index :reviews, [:user_id, :created_at]
add_index :reviews, [:property_id, :created_at]
end
end
<!--Applicable Code in properties/show.html.erb-->
<% if logged_in? %>
<div class="row" style="width:25% centered">
<section class="review_form">
<!-- #property.id correctly returns the id of the current property -->
<%= render 'shared/review_form', locals: {property_id: #property.id} %>
</section>
</div>
<% end %>
<!-- properties/show.html.erb -->
<% provide(:title, #property.title) %>
<!-- PROP TITLE -->
<div class="centered">
<h2><%=#property.title.upcase%></h2>
<h4><%=#property.address_street %></h4>
<h4>Owned by <%=#property.user.name%></h4>
</div>
<% form_for #property, :url=> {:action=> (#property.new_record? ? 'index' : 'new')} do |f| %>
<% end %>
<!-- PUTTING IN THE SLIDER -->
<div id="owl-demo" class="owl-carousel owl-theme">
<div class="item"><%= image_tag "lroom1.jpg" %></div>
<div class="item"><%= image_tag "lroom2.jpg" %></div>
<div class="item"><%= image_tag "room1.jpg" %></div>
<div class="item"><%= image_tag "room2.jpg" %></div>
<div class="item"><%= image_tag "room3.jpg" %></div>
</div>
<!-- DESCRIPTION TABLE -->
<div style="background-color:#F8F8F8; padding-top:30px ">
<table class="descrip centered">
<tr >
<td>Description</td>
<td class="col-content"><%=#property.summary %></td>
</tr>
<tr>
<td>The place</td>
<td class="col-content">Has <%=#property.num_bedroom %> beds</td>
</tr>
<tr>
<td></td>
<td class="col-content">Has <%=#property.num_bath %> bathroom</td>
</tr>
<tr>
<td>Owner</td>
<td class="col-content"><%=#property.title %></td>
</tr>
<tr>
<td>Address</td>
<td class="col-content"><%=#property.address_street %></td>
</tr>
</table>
<br />
<div>
<h1> Hello World <%= Property.find_by_id(params[:id]).id%> </h1>
<!--<body style="margin:0px; padding:0px;" onload="initialize()">-->
<table class="centered reviews">
<% #reviews.each do |d| %>
<tr>
<td>
<%= image_tag d.user.image %>
<p ><%= d.user.name %></p>
</td>
<td class="col-content">
<p>Contact at <%= d.user.email %><br /><br />"<%= d.description %>"</p>
</td>
</tr>
<% end %>
</table>
<% if logged_in? %>
<div class="row" style="width:25% centered">
<section class="review_form">
<!-- #property.id correctly returns the id of the current property -->
<%= render 'shared/review_form', locals: {property_id: #property.id} %>
</section>
</div>
<% end %>
<%= javascript_tag do %>
window.address = '<%= j #property.address_street %>';
<% end %>
<input id="pac-input" class="controls" type="text"
placeholder= "<%=#property.address_street %>" >
<div id="map_canvas" style="width:100%; height:500px;"></div>
</div>
<script>
$(document).ready(function() {
$("#owl-demo").owlCarousel({
autoPlay: 3000, //Set AutoPlay to 3 seconds
items : 4,
itemsDesktop : [1199,3],
itemsDesktopSmall : [979,3]
});
});
</script>
<!-- partial form _review_form.html.erb -->
<%= form_for(#review) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<div class="centered">
<h1> Property ID is <%=Property.find_by_id(params[:id]).id%>
</h1>
</div>
<div class="field">
<%= f.text_area :description, placeholder: "Create A Review" %>
</div>
<!-- Property.find_by_id(params[:id]).id correctly returns the id of the current property -->
<!-- The Following Line Returns The Error Message Below-->
<%= hidden_field_tag(:property_id, property_id) %>
<%= f.submit "Post", class: "btn btn-primary" %>
<% end %>
Error Message: undefined local variable or method `property_id' for #<#:0x007fbc03fcf820>
You are passing size: #property.id in your locals when you render the review form but then you are not using size. The #property instance variable in the view is not going to be available in the partial. Also, not sure why you are calling this variable "size".
So, in your main view, replace <%= render 'shared/review_form', locals: {size: #property.id} %> with <%= render 'shared/review_form', locals: {property_id: #property.id} %>. In your partial, replace <%= hidden_field_tag(:property_id, Property.find_by_id(params[:id]).id) %> with <%= hidden_field_tag(:property_id, property_id) %>.