I need to show notice/pop ups upon hitting of a button. Similar approaches are working in other views and controllers of the app but here on this Import button things are not working since long. None of the redirect_to
works in the controller while their similar usage in other controller works.
routes.rb
:
Rails.application.routes.draw do
namespace :admin do
get '', to: 'dashboard#index', as: 'root'
# resourceful routes
resources :oauth_clients
resources :tenants do
resources :sites do
#resources :production_shifts
resources :units do
resources :log_data_fields, only: [:import, :create, :index, :destroy, :download_csv] do
get :download_csv
# collection route
collection do
post :import #post action
end
end
log_data_fields_controller.rb
:
class Admin::LogDataFieldsController < Admin::BaseController
require 'csv'
# import request(this is gonna be a POST action)
def import
logger.debug("*****Testing the logger.*****")
file = params[:log_data_field][:file]
# return redirect_to [:admin, @tenant, @site, @unit], notice: "Only CSV please !!" unless file.content_type == "text/csv"
return redirect_to admin_tenant_site_unit_log_data_fields_url, notice: "Only CSV please !!" unless file.content_type == "text/csv"
file = File.open(file)
csv = CSV.parse(file, headers: true)
# csv = CSV.parse(file, headers: true, col_sep: ";")
@unit = Unit.find_by_id(params[:unit_id])
# p @unit.id
total_rows = CSV.read(file).count
count = 1
# binding.b
csv.each do |row|
tag_hash = {}
tag_hash[:name] = row["Name"]
tag_hash[:alias] = row["Alias"]
tag_hash[:column_type] = row["Type"]
tag_hash[:unit_id] = @unit.id
tag_hash[:is_active] = row["Active"]
# binding.b
# p row
logger.debug(" Mapping ")
@log_data_field = LogDataField.create(tag_hash)
# binding.b
if @log_data_field.save
count = 1
logger.debug("--------Saves--------")
# return redirect_to admin_tenant_site_unit_log_data_fields_path(@tenant, @site, @unit),
else
# return redirect_to admin_tenant_site_unit_log_data_fields_path(@tenant, @site, @unit),
# render :_importtags
end
end
logger.debug("-------------Going down----------")
if count == total_rows && count > 1
logger.debug("-------------All succeeded----------")
redirect_to admin_tenant_site_unit_log_data_fields_path(@tenant, @site, @unit), flash: { :notice => "Success"}
# flash.notice = "Success : Tags imported from CSV !"
elsif total_rows == 0
logger.debug("-------------All zero----------")
flash.alert = "Import Failure : CSV cant be empty"
render :action => 'index', :notice => "Import Failure : CSV cant be empty."
else
logger.debug("-------------Failed down----------")
flash.alert = "Import Failure"
render :action => 'index', :notice => "Import Failure"
end
redirect_to import_admin_tenant_site_unit_log_data_fields_url(@tenant, @site, @unit), notice:"Imported tags !"
end
_importtags.html.haml
:
%p{:style => "color: green"}= notice
= form_with model:@log_data_field, url: import_admin_tenant_site_unit_log_data_fields_path, method: :post do |form|
- if @log_data_field.errors.any?
#error_explanation
%h2= "#{pluralize(@log_data_field.errors.count, "error")} prohibited this log_data_field from being saved:"
%ul
- @log_data_field.errors.full_messages.each do |message|
%li= message
-# = link_to 'Download sample csv', [:admin, @tenant, @site, @unit, @log_data_field], method: :get
= form.file_field :file, accept: ".csv"
-# = form.file_field :file
<br>
<br>
-#button.btn.primary{:type => "submit", data: { disable_with: "Please wait..."}}
%button.btn.primary{:type => "submit"}
= "Import"
Comments are the things I have tried.
Sorry if you find the question or its structure very unprofessional but I am beginner and learning regularly. I need to render the view again upon hitting that Import
button to show either any errors if availabe or success on importing tags from csv. There is also issue of notice not being visible or popping up and redirect_to not working when non-csv document is submitted in the form which should give a warning too but it is not coming.
I believe the solution will be very short or some typo or silly mistake in understanding the path vs url routes.
EDIT As per @markets
suggestion I made all the redirect_to with return
which are used in between so the notice are working but they appear only on refresh. Still can't get them instantly on button click:
class Admin::LogDataFieldsController < Admin::BaseController
before_action :set_tenant
before_action :set_site
before_action :set_unit
require 'csv'
# import request(this is gonna be a POST action)
def import
logger.debug("*****Testing the logger.*****")
file = params[:log_data_field][:file]
# return redirect_to [:admin, @tenant, @site, @unit], notice: "Only CSV please !!" unless file.content_type == "text/csv"
return redirect_to admin_tenant_site_unit_log_data_fields_path(@tenant, @site, @unit), notice: "Only CSV please !!" unless file.content_type == "text/csv"
file = File.open(file)
csv = CSV.parse(file, headers: true)
# csv = CSV.parse(file, headers: true, col_sep: ";")
@unit = Unit.find_by_id(params[:unit_id])
# p @unit.id
total_rows = CSV.read(file).count
count = 1
# binding.b
csv.each do |row|
tag_hash = {}
tag_hash[:name] = row["Name"]
tag_hash[:alias] = row["Alias"]
tag_hash[:column_type] = row["Type"]
tag_hash[:unit_id] = @unit.id
tag_hash[:is_active] = row["Active"]
# binding.b
# p row
logger.debug(" Mapping ")
@log_data_field = LogDataField.create(tag_hash)
# binding.b
if @log_data_field.save
count = 1
logger.debug("--------Saves--------")
# return redirect_to admin_tenant_site_unit_log_data_fields_path(@tenant, @site, @unit),
# else
# return redirect_to admin_tenant_site_unit_log_data_fields_path(@tenant, @site, @unit),
# render :_importtags
end
end
logger.debug("-------------Going down----------")
if count == total_rows && count > 1
logger.debug("-------------All succeeded----------")
return redirect_to admin_tenant_site_unit_log_data_fields_path(@tenant, @site, @unit), flash: { :notice => "Success : Tags imported from CSV !"}
elsif total_rows == 0
logger.debug("-------------All zero----------")
return redirect_to admin_tenant_site_unit_log_data_fields_path(@tenant, @site, @unit), flash: { :notice => "Import Failure : CSV cant be empty"}
else
logger.debug("-------------Failed down----------")
return redirect_to admin_tenant_site_unit_log_data_fields_path(@tenant, @site, @unit), flash: { :notice => "Import Failure : PLease check CSV"}
end
redirect_to import_admin_tenant_site_unit_log_data_fields_url(@tenant, @site, @unit), notice:"Imported tags !"
end
CodePudding user response:
If you are calling render
or redirect_to
in the middle of a controller (not the last line), you should use return
too in order to stop the current execution path:
return redirect_to(...)
or
redirect_to(...) and return
More info: https://api.rubyonrails.org/v7.0.4/classes/ActionController/Redirecting.html