How to reload the page after action : create? - ruby-on-rails

When I attempt to add an item to the cart, it works but nobody can see it directly because the page is not reloading. How can I fix it ?
Here's my order_item_controller :
class OrderItemsController < ApplicationController
def create
#order = current_order
#order_item = #order.order_items.new(order_item_params)
#order.save
session[:order_id] = #order.id
end
and my views/product, with form_for :
<%= form_for order_item, remote: true do |f| %>
<%= product.firstdescription %>
<p class="bonus1">-Durée du cours : <%= product.duration %> minutes</p>
<p class="bonus">-<%= product.info %>
<p class="bonus">-En préparation</br>
<div class="talent">
<%= f.hidden_field :quantity, value: 1, class: "form-control", min: 1, max: 1 %>
<%= f.hidden_field :product_id, value: product.id %>
<div class="on_precommand">
<p id="old_price">
<del><%= currency_euro product.old_price %></del>
</p>
<p><%= currency_euro product.price %></p></br>
<%= product.tournage %></br>
</div>
<%= f.submit "Pré-commander", class: "addtocart" %>
<% end %>

All you need to do is a simple redirect, add this line at the end of the action
redirect_to #order
This will redirect to the show action of the new order.
EDIT:
Just noticed you are doing a remote: true request, so instead you need to create a js template create.js.erb for example, and add the javascript you want to be executed to add the created order in the view, here's an example:
$('#orders').append('<%= j( render #order ) %>')
Of coruse this is assuming that the orders div is has an id #orders

Related

How do i get the id of a model that i just created through form_with basically from one controller to another in Rails

Sort of new in rails so i might be doing things the wrong way
show.html.erb:
<% #feature.each do |p| %>
<br>
<h1><%= p.name %></h1>
<%= p.unit_price %>
<%= render partial: "shared/featureuse_form", locals: {feat_use: #feat_use , feature: p} %>
<%= button_to'Change' , feature_use_path(1) , :class => 'btn btn-primary' ,method: :delete %>
<% end %>
Right here in feature_use_path how do i get an id to pass it in order to make a delete button as i havent even created the model yet or its saved in its own controller should
_featureuse_form.html.erb:
<%= form_with model: feat_use do |f| %>
<%= f.number_field :total_units ,value: feature.max_unit_limit %>
<%= f.hidden_field :feature_id, value: feature.id %>
<%= f.hidden_field :usage_id, value: current_user.usage.id %>
<%= f.submit "confirm", id: "button"%>
<% end %>
Plans Controller
class PlansController < ApplicationController
before_action :authenticate_user!
def index
#plan = Plan.all
end
def show
#plan = Plan.find(params[:id])
#feature = #plan.features
#feat_use = FeatureUse.new
end
end
class FeatureUsesController < ApplicationController
def create
feature_use = FeatureUse.new(feature_use_params)
feature_use.total_units = params[:feature_use][:total_units]
feature_use.feature_id = params[:feature_use][:feature_id]
user = current_user.usage
feature_use.usage_id = user.id
feature_use.save
end
end
You're right that you can't create a button (method: :delete or otherwise) that relies on a record that doesn't yet exist.
Usually, a button like this would only be relevant to existing records anyway.
So, it's common to see an if statement like this:
<% if #feature_use.persisted? %>
<%= button_to 'Change' , feature_use_path(#feature_use.id) , :class => 'btn btn-primary', method: :delete %>
<% end %>
.persisted? returns false if the record is new and un-saved.

Rails:ArgumentError in MethodTypes#edit

I tried to make an edit for ruby on rails, but it shows me the argument error about the edit. I am confused about this question.
Then, I have tried to put the different argument into index.html.erb However, it still does not work. For example m.id and m
This is index.html.erb
<% #methodtypes.each do|m| %>
<tr>
<td><%=m.name %></td>
<td><%=m.desp %></td>
</tr>
<%= link_to "Edit", edit_method_types_path(m.id) %>
<% end %>
<%= link_to "Create Method", new_method_types_path %>
This is my controller file:
class MethodTypesController < ApplicationController
def index
#methodtypes = MethodType.all
end
def show
#methodtype = MethodType.find_by_id(params[:id])
end
def create
#methodtype = MethodType.new(method_params)
#methodtype.save
if #methodtype.save
redirect_to method_types_path
else
render :new
end
end
def edit
#methodtype = MethodType.find_by_id(params[:id])
end
def new
#methodtype = MethodType.new
end
private
def method_params
params.require(:method_type).permit(:name, :desp)
end
This is my edit page which is edit.html.erb:
<%= form_for #methodtype do |f| %>
<div>
<%= f.label :name %>
<%= f.text_area :name %>
</div>
<div>
<%= f.label :desp %>
<%= f.text_field :desp %>
</div>
<%= f.submit %>
<% end %>
The result should show that I can edit my text. but, it shows the ArgumentError in MethodTypes#edit. Does someone can give me some suggestion, I do not know how to fix that.....
Wrong edit url path
It should be <%= link_to "Edit", edit_method_type_path(m.id) %> instead of <%= link_to "Edit", edit_method_types_path(m.id) %>
Also check your routes file It seems you are defining
resource: method_types
Change to
resources: method_types
<%= link_to "Edit", edit_method_types_path(m.id) %> should be <%= link_to "Edit", edit_method_type_path(m) %>, note that type is in singular.
Run rails routes -g method_type to confirm it.
Also, change the MethodType.find_by_id(params[:id]) to MethodType.find(params[:id]) in the controller.
Btw, you are calling save twice in your create method:
def create
#methodtype = MethodType.new(method_params)
#methodtype.save # delete this line
if #methodtype.save
redirect_to method_types_path
else
render :new
end
end

Rails 4 - Combine Params from Previous Page (Pass Array in Hidden Field?)

On Rails 4. I'm working on an e-commerce app where a user can choose to go through a wizard-like process.
First the user selects a color scheme,
then selects products from two different pages,
then the results of those product selections are displayed on a fourth page.
No rows are created or updated in the database, I just want the results to be displayed on the fourth page (because this info is then fed to a third-party service).
Because the array would be no more than five or six choices, I am passing the product ids through the URL params. Here's the controller (let's say on the second page the user selects paper products and on the third page the user selects pencil products)
class WizardController < ApplicationController
def index
# Where the user clicks on a color scheme link
end
def paper
#color = ColorScheme.find(params[:color_scheme_id])
#product = Product.all
end
def paper_submit
respond_to do |format|
format.html { redirect_to wizard_pencils_path(
color_scheme_id: params[:color_scheme][:color_scheme_id],
id: params[:ids]) }
end
end
def pencils
#color = ColorScheme.find(params[:color_scheme_id])
#product = Product.all
#paper = Product.find(params[:id])
end
def pencils_submit
respond_to do |format|
format.html { redirect_to wizard_finish_path(
color_scheme_id: params[:color_scheme][:color_scheme_id],
id: params[:ids] + [:paper_ids]) } # ?? Not sure what goes here
end
end
def finish
# Haven't gotten here yet
end
private
def color_scheme_params
params.require(:wizard).permit(:color_scheme_id, :id)
# Also not too sure about this area either
end
end
Routes:
get '/wizard/paper', controller: 'wizard', action: 'paper'
put '/wizard/paper', controller: 'wizard', action: 'paper_submit'
get '/wizard/pencils', controller: 'wizard', action: 'pencils'
put 'wizard/pencils', controller: 'wizard', action: 'pencils_submit'
get '/wizard/finish', controller: 'wizard', action: 'finish'
resources :wizard
Form for the second page (selecting paper products)
<%= form_for([#color], html: {multipart: true}, url: {action: "paper_submit"}, method: 'put') do |f| %>
<%= f.hidden_field(:color_scheme_id, value: #color.id) %>
<div class="row">
<% #product.where(enabled: true, color_scheme_id: #color).each do |product| %>
<% if product.tags.where(name: "Paper").count > 0 %>
<div class="col-lg-3 col-md-4 col-sm-6">
<%= check_box_tag 'ids[]', product.id -%>
<%= link_to image_tag(product.thumbnail.url(:thumbnail_small_opt), alt: product.name), product %>
<p><%= link_to product.name, product %>, $<%= product.price %></p>
</div>
<% end %>
<% end %>
</div>
<div class="row">
<div class="col-lg-12">
<p style="text-align:right;"><%= f.submit "Next: Select Pencils", class: "btn bg-primary" %></p>
</div>
</div>
<% end %>
So far this all works fine. But, the problem is when the user makes product selections on the third page and reaches the fourth page. Ideally I want my application to combine the product id params from the second page with the different product ids from the third page.
<%= form_for([#color], html: {multipart: true}, url: {action: "embellishments_submit"}, method: 'put') do |f| %>
<%= f.hidden_field(:color_scheme_id, value: #color.id) %>
<!-- A hidden field maybe?? This does not work though -->
<%= f.hidden_field(:paper_ids, multiple: true, value: #paper) %>
<div class="row">
<% #product.where(enabled: true, color_scheme_id: #color).each do |product| %>
<% if product.tags.where(name: "Pencil").count > 0 %>
<div class="col-lg-3 col-md-4 col-sm-6">
<%= check_box_tag 'ids[]', product.id -%>
<%= link_to image_tag(product.thumbnail.url(:thumbnail_small_opt), alt: product.name), product %>
<p><%= link_to product.name, product %>, $<%= product.price %></p>
</div>
<% end %>
<% end %>
</div>
<div class="row">
<div class="col-lg-12">
<p style="text-align:right;"><%= f.submit "Next: Purchase Your Selections", class: "btn bg-primary" %></p>
</div>
</div>
<% end %>
It seems like a simple thing, I just want to combine an array from two different pages from the URL params but I can't figure out how to do this. Don't really want to use a gem for this because this is all I need to figure out. Thanks for any help.
Just put your variables into session:
def paper_submit
session[:paper_ids] = params[:ids]
respond_to do |format|
format.html { redirect_to wizard_pencils_path(
color_scheme_id: params[:color_scheme][:color_scheme_id]
) }
end
end
def pencils
#color = ColorScheme.find(params[:color_scheme_id])
#product = Product.all
#paper = Product.find(params[:id])
end
def pencils_submit
session[:pencil_ids] = params[:ids]
respond_to do |format|
format.html { redirect_to wizard_finish_path(
color_scheme_id: params[:color_scheme][:color_scheme_id]
) }
end
end
def finish
#all_products = Product.where(
enabled: true,
color_scheme_id: params[:color_scheme_id],
id: session[:paper_ids] + session[:pencil_ids]
)
end
finish.html.erb:
<% #all_products.each do |product| %>
<%= product.name %>
<br />
<% end %>
You should add those two arrays and make something like:
def pencils_submit
respond_to do |format|
format.html { redirect_to wizard_finish_path(
color_scheme_id: params[:color_scheme][:color_scheme_id],
product_ids: params[:ids] + [:paper_ids]) }
end
end
Then in your form:
<% #product_ids.each do |id| %>
<%= f.hidden_field_tag 'product_ids[]', id %>
<% end %>
Then in your last finish action do whatever you want.

Repopulate form after error validation from another controller Rails 4.0

I am really embarrassed with this problem :
I want to post comments from one view and if errors occurs in form, i want the form to be repopulated. I use the render method but my form isn't repopulated.
I specify that the form is displayed from a view and use another controller action, by other words means :
Form called from : views/cars/show.html.erb code below :
<h1>Fiche détaillée</h1>
<%= #car.marque %><br>
<%= #car.modele %><br>
<%= #car.nbkm %><br>
<%= #car.couleur %><br>
<%= #car.disponibilite %><br>
<hr>
<% x=0 %>
<h1><%= pluralize(#car.comments.count, 'commentaire') %></h1>
<% #car.comments.each do |k| %>
<%= x+=1 %>
Email : <%= k.email %><br>
Sujet : <%= k.sujet %><br>
Commentaire : <%= k.commentaire %><br>
<%= link_to 'Supprimer', [k.car, k], method: :delete %><br><br>
<% end %>
<hr>
<h1>Ajouter votre commentaire</h1>
<div style='width:300px;'>
<% flash.each do |key, msg| %>
<% if msg.count >0 %>
<p class="bg-danger" style='padding:10px;'><%= pluralize(msg.count,'error') %>
<ul><% msg.full_messages.each do |m|%>
<li><%= m %></li>
<% end %>
</p>
<% end %>
<% end %>
</ul>
<%= form_for([#car,#car.comments.build]) do |co| %>
<%= co.label :'Email' %><br>
<%= co.text_field :email , class: 'form-control' %><br>
<br>
<%= co.label :'Sujet' %><br>
<%= co.text_field :sujet , class: 'form-control'%><br>
<br>
<%= co.label :'Commentaire' %><br>
<%= co.text_area :commentaire , class: 'form-control' %><br>
<br>
<%= co.submit :'Envoyer votre commentaire', class: 'btn btn-info'%>
<% end %>
</div>
below my controllers :
Controller 1 : controllers/cars_controller.rb
def create
#render text: params[:car].inspect
#car = Car.new(params[:car].permit(:marque,:modele,:nbkm,:couleur,:disponibilite))
if !#car.save
render 'new'
else
redirect_to #car
end
end
def show
#car = Car.find(params[:id])
end
def index
#cars=Car.all
end
Controller 2 : controllers/comments_controller.rb
class CommentsController < ApplicationController
def new
#comment=Comment.new
end
def create
#car = Car.find(params[:car_id])
#comment = #car.comments.create(params[:comment].permit(:email,:sujet,:commentaire))
if !#comment.save
flash[:error] = #comment.errors
flash.keep[:error]
render 'cars/show'
else
redirect_to car_path(#car)
end
end
def destroy
#car = Car.find(params[:car_id])
#comment = #car.comments.find(params[:id])
#comment.destroy
redirect_to car_path(#car)
end
end
I really don't understand why it does not work !!
Thank you so much for any assistance ;)
Edited:
I did some similar tests a bit for your case, the problem should due to the flash method.
Replace below lines:
flash[:error] = #comment.errors
flash.keep[:error]
render 'cars/show'
To:
flash.now[:error] = #comment.errors.full_messages
#car.reload
render 'cars/show'
Because flash[:error] will only be available in next action, means only works in redirect_to, so you have to use flash.now[:error] for rendering same view template. And most importantly, though the save failed of the #comment, the comment list in #car will still receive an instantiated invalid object return by the comment's create, build, or new method. It is because these three methods will always return instantiated object to the #car.comments collection, though it is failed to save it. So we must reload the #car object by #car.reload to refresh the memory and get correct Comment collection from the database.
Previous response:
In crate action, the create method #car.comments.create(..) will directly create and return an instantiated object without given attributes then try to save it if it passed the validation. If you have not set validations for Comment model, then it will directly save it. Try #car.comments.new(..) or #car.comments.build(..) for collection associations, it will not force to save an instantiated object after the validation passed. Also, check your Comment model for setting the validations.

RoR Ransack Searching issue

I have two different controllers (scholarships_controller, scholarships_browse_controller) that look at the scholarship model. I want my Ransack search function to show the search results on the current page. So, for example, if I am on /scholarships_browse and I use the search functionality, I want it to use the scholarships_browse_controller and show the results on /scholarships_browse.
Currently, if I search on /scholarships_browse it uses the scholarships_controller and redirects to /scholarships to show the results (instead of /scholarships_browse).
Code for ScholarshipsBrowseController and ScholarshipsController
def index
#search = Scholarship.search(params[:q])
#scholarships = #search.result.page(params[:page]).per(3) #allows 3 scholarships on a page at a time
#search.build_condition
respond_to do |format|
format.html # index.html.erb
format.json { render json: #scholarships }
end
end
Code for scholarships browse index.html.erb:
<%= search_form_for #search do |f| %>
<%= f.condition_fields do |c| %>
<div class="field">
<%= c.attribute_fields do |a| %>
<%= a.attribute_select %>
<% end %>
<%= c.predicate_select compounds: false, only: [:cont, :eq, :gt, :lt] %>
<%= c.value_fields do |v| %>
<%= v.text_field :value %>
<% end %>
</div>
<% end %>
<div class="actions"><%= f.submit "Search" %></div>
<% end %>
So, I guess specifically I'm asking how do I make sure I am using the ScholarshipsBrowseController index instead of ScholarshipsController index when I am on /scholarships_browse ?
On your view:
<%= search_form_for #search, url: RAILS_ROUTEHERE do |f| %>
...
<%- end %>
search_form_for its an extension for form_for, so you can use the :url parameter to tell the form what should be the action of it (you can check the page source code when you render it on browser, you can check the tag <form action=""> to make sure it points to the right route.

Resources