【问题标题】:Rails routing bug in "redirect_to" and "notice" flash message\"redirect_to\" 和 \"notice\" flash 消息中的 Rails 路由错误
【发布时间】:2022-11-26 20:49:10
【问题描述】:

我需要在按下按钮时显示通知/弹出窗口。类似的方法在应用程序的其他视图和控制器中也有效,但在此“导入”按钮上,很长时间以来都不起作用。 redirect_to 都不能在控制器中工作,而它们在其他控制器中的类似用法可以工作。

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"

评论是我尝试过的东西。

抱歉,如果您发现问题或其结构非常不专业,但我是初学者并且经常学习。我需要在点击 Import 按钮时再次渲染视图,以显示任何错误(如果可用)或成功从 csv 导入标签。当非 csv 文档以应该发出警告但没有出现的形式提交时,还存在通知不可见或弹出和 redirect_to 不工作的问题。

我相信解决方案将非常简短,或者在理解路径与 url 路由时出现一些拼写错误或愚蠢的错误。

编辑根据@markets的建议,我用return做了所有的redirect_to,它们在两者之间使用,所以通知有效,但它们只在刷新时出现。单击按钮仍然无法立即获得它们:

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

【问题讨论】:

  • 应该是return and redirect_to admin_tenant_site_unit_log_data_fields_url
  • 不@Vishal 它给出错误void value expression return and redirect_to admin_tenant... ^~~~~~

标签: ruby-on-rails redirect ruby-on-rails-6 rails-routing


【解决方案1】:

如果你在控制器中间调用renderredirect_to(不是最后一行),你也应该使用return来停止当前的执行路径:

return redirect_to(...)

或者

redirect_to(...) and return

更多信息:https://api.rubyonrails.org/v7.0.4/classes/ActionController/Redirecting.html

【讨论】:

  • 谢谢!现在至少其他作品的通知即将到来,但仍然只是刷新。请帮助我在编辑部分添加了编辑后的代码
  • 那是另一个问题,您应该将其发布在一个新问题中(并接受这个问题或给予一些信任……因为它似乎解决了您的一个原始问题)。当前的问题太大了,可能没有人能够理解当前的情况以及 OP 中所做的所有“更新”。
  • 好吧,好吧,我接受了,但问题的主要部分仍然是“即时按钮单击时不会弹出通知”。在这方面我仍然需要帮助,所以我部分接受了您的回答,我很感激能提高您在 stackOverflow 上的声誉,先生。而且,如果您不理解我的问题,那么我很抱歉我的结构不佳,因为我正在尝试提供与问题相关的所有内容,以便在传达问题的根源时不会留下任何空白。期待解决方案。
  • 没问题先生!但考虑到所做的更新,当前的问题可能太大而无法理解它并牢记所有上下文。现在我们解决了主要问题,您可以发布一个“重点”(简短,但包含所有相关信息)关于 flash 消息的新问题,很确定有人会帮助您(如果您提供给我,我也会看看关联)。
  • 是的,非常感谢您的帮助,我意识到了许多 Rails 概念,并找到了我在这里为这个问题回答的解决方案:D
【解决方案2】:

在查看我的应用程序其他组件的形式后,我注意到我的form_with 中存在问题,因此我通过阅读 Rails 文档https://api.rubyonrails.org/v5.2/classes/ActionView/Helpers/FormHelper.html#method-i-form_for 将其更改为form_for 助手

所以这是 _importtags.html.haml 的工作代码:

= form_for @log_data_field, url: import_admin_tenant_site_unit_log_data_fields_url do |f|
  - if @log_data_field.errors.any?
    #error_explanation
      %ul
        - @log_data_field.errors.full_messages.each do |message|
          %li= message

  .input-field.m0
    = f.file_field :file, accept: ".csv"
    -# = f.file_field :file
  %br
  %br
  %br

  .row
    .col.s5
      %button.btn.primary{type: 'submit', data: { disable_with: "Please wait..."}}
        Save

不需要专门传递 method: :post ,因为导入已经是 routes.rb 中定义的后期操作

除此之外,@markets 在此线程中建议和回答的内容也非常有帮助并被接受。感谢市场!

【讨论】:

    猜你喜欢
    • 2011-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多