Params problems - ruby-on-rails

I'm doing my first web api on Ruby on Rails (It's a Sale Point). The think here It's makes 'n' sales. So I used the nested_form for doing that, but when I 'confirm' the sale I'm having this problem:
ActionController::ParameterMissing in SalesController#create
param is missing or the value is empty: sale
private
def sale_params
params.require(:sale).permit(:fecha_venta, :id_usuario, carts_attributes: [:id ,:id_producto, :cantidad])
end
whith the strong params.This is controller for 'sale'
class SalesController < ApplicationController
def new
#venta = Sale.new
end
def create
#venta = Sale.new(sale_params)
#venta.id_usuario= current_user.id
#venta.fecha_venta = DateTime.now
if #venta.save
flash[:succes] = "Se ha realizado la venta"
redirect_to sales_index_path
else
flash[:danger] = "Ha ocurrido un error"
render new_sale_path
end
end
private
def sale_params
params.require(:sale).permit(:fecha_venta, :id_usuario, carts_attributes: [:id ,:id_producto, :cantidad])
end
end
I'm using nested_form in the model (and I've already installed the gem "nested_form"). Here is the sale and the cart model:
class Sale < ApplicationRecord
has_many :carts
accepts_nested_attributes_for :carts
end
class Cart < ApplicationRecord
belongs_to :sale
end
And finaly this is the partial form that I'm using
<%= nested_form_for(#venta) do |f| %>
<div class="form-group col-md-12">
<label class="form-control">Vendedor: <%= current_user.nombre_trabajador%></label>
</div>
<%= f.fields_for :carts do |carro| %>
<form class="form-horizontal">
<div class="card-body">
<div class="form-row">
<div class="form-group col-md-5">
<%= carro.collection_select :id_producto, Product.select("products.nombre_producto, products.stock, products.id").where("products.stock > ?", 0), :id, :nombre_producto, {:include_blank => true}, {:class => 'form-control btn btn-secondary dropdown-toggle'} %>
</div>
<div class="form-group col-md-5">
<%= carro.text_field :cantidad, class: "form-control", type: 'number' %>
</div>
<div class="form-group col-md-2">
<%= carro.link_to_remove "Eliminar", :class=> 'btn btn-danger btn-sm' %>
</div>
</div>
</div>
</form>
<% end %>
<div class="row">
<div class="form-actions">
<%= f.link_to_add "Agregar Producto", :carts , :class=> 'btn btn-default btn-sm'%>
</div>
</div>
<br>
<div class="form-actions">
<%= f.submit "Enviar" , :class=> 'btn btn-primary'%>
<%= link_to 'Cancelar', sales_index_path ,:class=> 'btn btn-danger' %>
</div>
<% end %>
I've benn traying to makea solution all day, but nothing.

Related

search function not working - Ruby on rails

I'm new to Ruby on Rails and trying to implement a search function with simple form to filter out availabilities results. After I press search button, it still stays on the same page and not running the search function in the controller. The permitted is false. I'm wondering why this might occur. Is there anything wrong with the search_params I wrote?
Rails version is 6.0.2.1.
views/availabilities/_searchform.html.erb
<form>
<div id="aDiv">
<%= simple_form_for :search, :url => search_rides_result_path, :method => :get do |f| %>
<div class="form-row">
<div class="form-group col-md-2">
<%= f.input :start_city, label: 'Start City', class: "form-control", error: 'Start address is mandatory, please specify one' %>
</div>
<div class="form-group col-md-4">
<%= f.input :start_street_address, label: 'Start Street Address', class: "form-control" %>
</div>
</div>
<div class="form-row">
<div class="form-group col-md-2">
<%= f.input :end_city, label: 'Destination City', class: "form-control" %>
</div>
<div class="form-group col-md-4">
<%= f.input :end_street_address, label: 'Destionation Street Address', class: "form-control" %>
</div>
</div>
<div class="form-row">
<div class="form-group col-md-4">
<%= f.input :trip_time, as: :datetime, inline_label: 'Yes, remember me', class: "form-control" %>
</div>
<div class="form-group col-md-2">
<%= f.input :lowest_acceptable_price, label: 'Expected Price', class: "form-control" %>
</div>
</div>
<%= f.submit "Search", class: "btn btn-primary" %>
<% end %>
</div>
</form>
routes.rb file.
get 'search_rides', to: "availabilities#index"
get 'search_rides_result', to: "availabilities#search"
availabilities_controller.rb
def index
#availabilities = Availability.unmatched
end
def search
#availabilities = Availability.unmatched.search(search_params[:start_city])
end
def search_params
params.require(:search).permit(:start_city, :start_street_address, :end_city, :end_street_address, :trip_time, :lowest_acceptable_price)
end
models/availability.rb
class Availability < ApplicationRecord
has_many :users, :through => :posts
has_one :request
scope :unmatched, ->{ where(matched_request_id: -1) }
def self.search (params)
puts "start searching"
results = city_matches(start_city, end_city, params[:start_city], params[:end_city])
return nil unless results
results
end
Instead of using 2 different methods for search, try combining both in index method. Your index method will now look as follows:
def index
if params[:search]
#availabilities = Availability.unmatched.search(search_params[:start_city])
else
#availabilities = Availability.unmatched
end
end
Change the form url to search_rides_path. This way search results will be rendered in same view upon form submission.

Nested form validation in Rails

I have the following code:
<%= form_with(model: [#lawsuit, #lawsuit.suits.build]) do |f| %>
<fieldset>
<legend>New Suit</legend>
</fieldset>
<br />
<div class="form-group">
<%= f.label :claim %>
<%= f.text_field :claim, class: 'form-control', placeholder: 'Name' %>
</div>
<div class="form-group">
<%= f.label :sentence %>
<%= f.text_area :sentence, class: 'form-control', placeholder: 'Sentence' %>
</div>
<div class="form-group">
<%= f.label :result %>
<%= f.select(:result, [['Not Favorable', false], ['Favorable', true]], {}, {class: 'form-control'}) %>
</div>
<%= button_tag type: 'submit', class: "btn btn-primary float-right" do %>
<i class="fa fa-plus" aria-hidden="true"></i>
Create
<% end %>
<% end %>
How can I show the list of errors of the suit (which is a nested attribute of #lawsuit) and show it's errors on the screen ? I have already done the validations on the model. The model is like that:
class Suit < ApplicationRecord
belongs_to :lawsuit
validates_presence_of :claim, :sentence
end
My controllers are like below.
The process start in lawsuit controller. There I build the #suit (which is used in the form).
Suit controller:
class SuitsController < ApplicationController
before_action :set_suit, only: [:show]
def new
end
def create
Rails.logger.info "=====================SUIT CREATION"
#lawsuit = Lawsuit.find(params[:lawsuit_id])
#suit = #lawsuit.suits.build(suit_params)
Rails.logger.info "AISHA #{#suit.errors.any?}"
# #suit = #lawsuit.suits.new(suit_params)
if #suit.save
flash[:notice] = "Suit created successfully"
redirect_to lawsuit_path(#lawsuit)
else
Rails.logger.info "AISHA #{#suit.valid?}"
flash[:alert] = "Something went wrong"
redirect_to lawsuit_path(#lawsuit)
end
end
Lawsuit Controller
class LawsuitsController < ApplicationController
before_action :set_lawsuit, only: [:show]
def index
#lawsuits = Lawsuit.paginate(:page => params[:page], :per_page => 8)
end
def show
begin
#blob = Lawsuit.get_blob_for_document(#lawsuit.document_number)[1]
rescue
#blob = "Cannot load document!"
flash[:error] = "Cannot load document!"
end
#lawsuit = Lawsuit.find(params[:id])
#suit = #lawsuit.suits.build
end
private
def set_lawsuit
#lawsuit = Lawsuit.find(params[:id])
end
def lawsuit_params
params.require(:lawsuit).permit(:document_number, :region, :court, :noted)
end
end
Modify view as follows
<%= form_with(model: [:lawsuit, #suit]) do |f| %>
<fieldset>
<legend>New Suit</legend>
</fieldset>
<br />
<% if #suit.errors.any? %>
<div id="error_explanation">
<h2>
<%= pluralize(#suit.errors.count, "error") %>
<%= "prohibited this suit from being saved:" %>
</h2>
<ul></ul>
<% #suit.errors.full_messages.each do |message| %>
<li>
<%= message %>
</li>
<% end %>
</div>
<% end %>
<div class="form-group">
<%= f.label :claim %>
<%= f.text_field :claim, class: 'form-control', placeholder: 'Name' %>
</div>
<div class="form-group">
<%= f.label :sentence %>
<%= f.text_area :sentence, class: 'form-control', placeholder: 'Sentence' %>
</div>
<div class="form-group">
<%= f.label :result %>
<%= f.select(:result, [['Not Favorable', false], ['Favorable', true]], {}, {class: 'form-control'}) %>
</div>
<%= button_tag type: 'submit', class: "btn btn-primary float-right" do %>
<i class="fa fa-plus" aria-hidden="true"></i>
Create
<% end %>
<% end %>
note you should build #suit object from controller action first
#suit = #lawsuit.suits.build
and you controller should be
class SuitsController < ApplicationController
before_action :set_suit, only: [:show]
def new
end
def create
#lawsuit = Lawsuit.find(params[:lawsuit_id])
#suit = #lawsuit.suits.build(suit_params)
if #suit.save
flash[:notice] = "Suit created successfully"
redirect_to lawsuit_path(#lawsuit)
else
render :form
end
end
Or
If you want to display flash message then you should write following code on view
<% flash.each do |key, value| %>
<div class="alert alert-<%= key %>"><%= value %></div>
<% end %>

unable to do validations in rails

I have a contact us page
class ContactPagesController < ApplicationController
def new
#contact_page = ContactPage.new
end
def create
#contact_page = ContactPage.new(contact_page_params)
if #contact_page.save
flash[:notice]="details saved successfully"
redirect_to contact_pages_path
else
flash[:notice]="details not saved"
redirect_to contact_pages_path
end
# if #contact_page.errors.any?
# flash[:notice]="there are errors"
# end
end
private
def contact_page_params
params.require(:contact_page).permit( :first_name, :last_name, :email, :phone, :do_you_have_land, :moving_time_frame, :financing, :to$
end
end
and my model
class ContactPage < ApplicationRecord
validates :email, presence: true
end
and the view
new.html.erb
<%= form_for #contact_page, :html => { :class => 'form-horizontal', multipart: true } do |f| %>
<% if #contact_page.errors.any? %>
<div id="error_explanation">
<h3>
<%= pluralize(#contact_page.errors.count, "error") %>
prohibited this employee from being saved:
</h3>
<ul>
<% #contact_page.errors.full_messages.each do |message| %>
<li>
<%= message %>
</li>
<% end %>
</ul>
</div>
<% end %>
<div class="control-group">
<%= f.label :First_Name, :class => 'control-label' %>
<div class="controls">
<%= f.text_field :first_name, :class => 'text_field' %>
</div>
</div>
<div class="control-group">
<%= f.label :Email, :class => 'control-label' %>
<div class="controls">
<%= f.text_field :email, :class => 'text_field' %>
</div>
</div>
<div class="control-group">
<%= f.label :How_can_we_assist_you, :class => 'control-label' %>
<div class="controls">
<%= f.text_field :assist_you, :class => 'text_field' %>
</div>
</div>
<div class="form-actions">
<%= f.submit nil, :class => 'btn btn-primary' %>
</div>
<% end %>
If all the fields are filled the data is being saved into the database.If email is left blank data is also not being saved inside the database(due to validation), but the error message is also not rendering . The #contact_page.errors.any? inside the view page is being ignored for some reason.I am expecting an error "email can't be blank" on the top of the form.
why the save action is not triggering the validation errors?
my routes for contact page
get 'contact_pages' => 'contact_pages#new', :as => 'contact_pages'
post 'contact_pages' => 'contact_pages#create'
Need help in what I have gone wrong.Any help is highly appreciated.Thanks in advance.
class SaveController < ApplicationController
def new
#contact_page = ContactPage.new
end
def create
if
#contact_page.save
flash[:notice]="Successfuly stored"
redirect_to contact_pages_path
else
flash[:notice]="please check your inputs"
render :new
end
end
end
In View: -
<% if notice %>
<div class="alert alert-success alert-dismissible" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button>
<%= notice %>
</div>
<% end %>
you should user render on error not redirect
def create
#contact_page = ContactPage.new(contact_page_params)
if
#contact_page.save
flash[:notice]="details saved successfully"
redirect_to contact_pages_path
else
flash[:notice]="details not saved"
render :new
end
end

ActionController::InvalidAuthenticityToken when i am using collection_select in form_for tag

i am new to ruby on rails.
i am trying to send data selected by select option, but on create action ActionController::InvalidAuthenticityToken is raised and i can't figure out why.
if i remove collection_select line from form then form submits.
app/views/codes/new.html.erb
<%= form_for #code, url: {action: "create"}, html: {class: "form-horizontal form-bordered"} do |f| %>
<div class="form-body">
<div class="form-group TextBoxContainer">
<label class="control-label col-md-2"> Tracking Code(s) </label>
<div class="col-md-6">
<%= f.text_field :code, name: "[code][]" , class: "form-control",placeholder: "Enter Tracking Code(s) for Analytics" %>
</div>
<div class="actions col-md-4 div_tag">
<button type="button" class="btn dark btn-outline add_another_code">
<i class="fa fa-plus"></i> Add Another Code</button>
</div>
</div>
</div>
<!-- <%= f.collection_select(:webpage_id,Webpage.all, :id, :title,{prompt: true})%> -->
<%= f.button :submit, class: 'btn red btn-lg' %>
<% end %>
this is my codes_controller.rb
app/assets/controller/codes_controller.rb
class CodesController < ApplicationController
def new
#code = Code.new
end
def create
debugger
#code = Code.new
#code.webpage_id = params[:webpage_id]
params[:code].each do |code|
#code.code << code
end
if #code.save
redirect_to '/'
else
render 'new'
end
end
def edit
#code = Code.find(params[:id])
end
def update
#code = Code.find(params[:id])
if #code.update(code_params)
redirect_to '/'
else
render 'edit'
end
end
private
def code_params
params.require(:code).permit(:webpage_id,code:[])
end
end
Try this one:
<%= f.select :webpage_id, Webpage.all.map {|c| [c.title, c.id] }, {prompt:"Choose Webpage"} %>

form_for first argument cannot be nil or empty in rails 4

I've seen this question come up on SO a few times and have tried to the recommended approaches to solve the problem. I'm still encountering this error for my form_for:
First argument in form cannot contain nil or be empty
I have several fields that should be entered into a 'Charge' object. I want the form to submit and create a charge object that includes the proper fields that I have in the form, including the hidden fields (user_id and gift_id).
Models:
class Gift
has_many :codes
has_many :charges
class Code
belongs_to :gift
class Charge
belongs_to :user
belongs_to :gift
class User
has_many :charges
charges_controller.rb
class ChargesController < ApplicationController
skip_before_filter :verify_authenticity_token, :only => [:new, :create]
def index
#charges = Charge.all
end
def show
#charge = Charge.find(params[:id])
end
def new
#charge = Charge.new
end
def create
#charge = Charge.new(params[:charge_params])
Stripe.api_key = "sk_test_Ig7H6rhd0jl7W3V48y5pleOa"
token = params[:stripeToken]
customer = Stripe::Customer.create(
:card => token,
:description => "payinguser#example.com"
)
Stripe::Charge.create(
:amount => gift.price,
:currency => "cad",
:customer => customer.id
)
save_stripe_customer_id(user, customer.id)
# Later...
customer_id = get_stripe_customer_id(user)
Stripe::Charge.create(
:amount => 1500,
:currency => "cad",
:customer => customer_id
)
if #charge.save
redirects_to gifts_path, flash[:notice] = 'It worked'
else
render 'gifts/new'
end
end
def edit
#charge = Charge.find(params[:id])
end
def update
#charge = Charge.find(params[:id])
#charge.update_attributes(charge_params)
end
def destroy
#charge = Charge.find(params[:id])
#charge.destroy
end
private
def charge_params
params.require(charge).permit(:sender_name, :recipient_email, :recipient_msg, :stripeToken, :gift_id, :user_id)
end
end
_new.html.erb (the form collecting the data)
<%= form_for #charge do |f| %>
<%= f.hidden_field :gift_id %>
<%= f.hidden_field :user_id %>
<div class="form-group left-inner-addon">
<i class="glyphicon glyphicon-send"></i>
<%= f.text_field :sender_name, :class => "form-control", :placeholder => "Sender's Name" %>
</div>
<div class="form-group left-inner-addon">
<i class="glyphicon glyphicon-send"></i>
<%= f.email_field :recipient_email, :class => "form-control", :placeholder => "Recipient's Email" %>
</div>
<div class="form-group left-inner-addon">
<i class="glyphicon glyphicon-pencil"></i>
<%= f.text_field :recipient_msg, :class => "form-control", :placeholder => "Message to Recipient" %>
</div>
<div class="form-group left-inner-addon ">
<i class="glyphicon glyphicon-credit-card"></i>
<%= f.text_field "data-stripe" => "number", :class= => "form-control", :placeholder => "Credit Card Number" %>
</div>
<div class="form-group">
<div class="row">
<div class="col-xs-4 left-inner-addon ">
<i class="glyphicon glyphicon-calendar"></i>
<%= f.text_field "data-stripe" => "exp-month", :class => "form-control", :placeholder => "MM" %>
</div>
<div class="col-xs-5 left-inner-addon ">
<i class="glyphicon glyphicon-calendar"></i>
<%= f.text_field "data-stripe" => "exp-year", :class => "form-control", :placeholder => "YYYY" %>
</div>
</div>
</div>
<div class="form-group">
<div class="row">
<div class="col-xs-5 left-inner-addon ">
<i class="glyphicon glyphicon-ok-circle"></i>
<%= f.text_field "data-stripe" => "cvc", :class => "form-control", :placeholder => "CVC" %>
</div>
</div>
</div>
<%= f.submit :class => "btn btn-primary", :type => "submit" %>
<% end %>
_show.html.erb (the partial that renders the form)
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title"><center><%= gift.name %></center></h4>
</div>
<div class="modal-body">
<p><%= image_tag gift.picture.url(:mobile) %></p>
<p><%= gift.description %></p>
<p>$<%= gift.price %></p>
<%= render partial: 'charges/new', :locals => { :gift => gift } %>
</div>
<div class="modal-footer">
</div>
index.html.erb (Page that renders the _show.html.erb partial)
<%= title "Redwood | Gifts" %>
<div class="container">
<div class="row" id="item">
<% #gifts.each do |gift| %>
<div class="col-sm-6 col-md-4">
<div class="thumbnail">
<%= image_tag gift.picture.url(:medium) %>
<div class="caption">
<h3><%= gift.name %></h3>
<h4><%= link_to gift.merchant.name, merchant_path(gift.merchant.id) %></h4>
<p><%= gift.description %></p>
<p><%= link_to 'Buy', gift_path(gift), :remote => true, 'data-toggle' => "modal", 'data-target' => "#myModal#{gift.id}", :class => "btn btn-primary", 'data-type' => "html" %></p>
</div>
<!-- Modal -->
<div class="modal fade" id="myModal<%= gift.id %>">
<div class="modal-dialog">
<div class="modal-content">
<%= render partial: 'show', :locals => { :gift => gift } %>
</div>
</div>
</div>
<!-- End of Modal -->
</div>
</div>
<% end %>
</div>
</div>
Your 'new' partial is being rendered by your 'show' partial and then that 'show' partial is being rendered by your 'index' view. That means it's only the code in your 'index' action that's being run. Since you don't instantiate an instance variable called #charge in your index action, #charge will return nil in the 'new' partial. That's why you get that error.
To fix that error, you should either add the below code to your index action:
#charge = Charge.new
That way, #charge will return an instance of Charge and not nil. You could also choose not to use a 'new' partial and just display the form for creating a new charge in a 'new' view of its own so that it runs the code in the 'new' action.
Hope that helps!
In ChargesContorller::index you create a variable called #chargeS. Then in the _new.html.erb you are using #charge (no s).
To get your code to work, you can initiate a new #charge variable in index (besides #charges), or use Charge.new in the form, in place of #charge.
What I think confuses you, because it confused me until I figured it out, it that the render function DOES NOT run the method in the controller (in you case ChargesContorller::new), but only goes directly to the view and renders it. I may be mistaken here because your new is a partial which isn't connected to a controller method anyway (and running new from index seems weird to me). In any case you need to initialize your variable.

Resources