如何处理ActiveStorage直接上传的ActiveSupport :: MessageVerifier :: InvalidSignature错误

时间:2019-03-03 05:03:42

标签: rails-activestorage ruby-on-rails-5.2

我有一个表单,用户可以在其中选择要上传的文件。使用ActiveStorage直接上传选择文件后,文件即被上传。有一个提交按钮,只有在上传完成后才能单击。

加载表单时,该按钮被禁用。但是,如果由于某种原因用户能够在不首先选择文件的情况下单击该按钮,则控制器中将出现以下错误:

ActiveSupport::MessageVerifier::InvalidSignature - ActiveSupport::MessageVerifier::InvalidSignature:

我想确保我的应用程序是可靠的,所以我想知道如何处理此错误。

这是我的控制器方法:

def create
  authorize [:proofreaders, :proofread_document]
  @proofread_document = ProofreadDocument.build(proofread_document_params.merge(uploader: current_user, proofreading_job: @proofreading_job))
  if @proofread_document.save
    flash[:notice] = I18n.t('success.upload', resource: @proofread_document.file.filename)
    render :create, layout: false
  else
    render :new, layout: false
  end
end

我试图解决此问题的方法是创建自己的“生成”方法并使用它而不是标准的“新”方法,因为“新”会引起控制器中的错误,并且我想在模型中进行处理。

模型中的“构建”方法:

  def self.build(params)
    pd = self.new params.except(:file)
    pd.file = params[:file]
    pd
  rescue ActiveSupport::MessageVerifier::InvalidSignature => e
    pd
  end

我必须分别将文件属性值分配给模型,以便在出现错误之前分配其他属性。

这可以工作,因为它返回发生错误之前已建立的模型实例,并且文件验证将检查空文件值。但是,这真的是正确的吗?有经验的和熟练的开发人员使用的更好的方法吗?

2 个答案:

答案 0 :(得分:0)

我知道如何解决这个问题的方法是修改参数以拒绝空白值。例如

params[:user].delete(:avatar) if params[:user][:avatar].blank?

这有效,但它会使您的控制器操作更难查看我想在模型方面解决这个问题,所以我会这样做并告诉您结果如何。

答案 1 :(得分:0)

出于某种原因,这解决了我的问题。

from matplotlib import pyplot as plt
import numpy as np


def bar_plot(ax, data, colors=None, total_width=0.8, single_width=1, legend=True):
    

    # Check if colors where provided, otherwhise use the default color cycle
    if colors is None:
        colors = plt.rcParams['axes.prop_cycle'].by_key()['color']

    # Number of bars per group
    n_bars = len(data)

    # The width of a single bar
    bar_width = total_width / n_bars

    # List containing handles for the drawn bars, used for the legend
    bars = []

    # Iterate over all data
    for i, (name, values) in enumerate(data.items()):
        # The offset in x direction of that bar
        x_offset = (i - n_bars / 2) * bar_width + bar_width / 2

        # Draw a bar for every value of that type
        for x, y in enumerate(values):
            bar = ax.bar(x + x_offset, y, width=bar_width * single_width, color=colors[i % len(colors)])

        # Add a handle to the last drawn bar, which we'll need for the legend
        bars.append(bar[0])

    # Draw legend if we need
    if legend:
        ax.legend(bars, data.keys())


if __name__ == "__main__":
    # Usage example:
    data = {
        "False": [100.16,  30.04, 50.04, 120.19],
        "True": [1100.08,  600.06, 650.06, 1050.17],
        #"RMSE":[0.39,  0.19, 0.20, 0.44,  0.45,  0.26],
            }

    fig, ax = plt.subplots(figsize=(8, 6))
    
    y_pos = np.arange(len(objects))
    for i, v in enumerate(data['False']):
        plt.text(y_pos[i] - 0.35, v + 10.213, str(v))

    for i, v in enumerate(data['True']):
        plt.text(y_pos[i] + 0.05, v + 10.213, str(v))


    #plt.rc('font', **font)
    bar_plot(ax, data, total_width=.8, single_width=.9)
    #font = font_manager.FontProperties(family='Comic Sans MS', weight='bold', style='normal', size=16)
    font = {'family' : 'normal',
            'weight' : 'bold',
            'size'   : 15,
             'family':'Times New Roman'}
    #font = {'family':'Times New Roman', 'weight' :'normal','size':15}
    
    ax.set_xticklabels( ('0',' ','Business Finance',' ','Graphic Design',' ', 'Musical Instruments',' ', 'Web Development') , rotation=45, ha="right")#, **font )
    #ax.set_yticklabels( data['MSE'] ,**font )
    ax.set_ylabel('Count  ')#, **font)
    ax.set_xlabel('Subject  ')#, **font)
    ax.set_title('Figure 10/ Table 6 for is_paid')#, **font)
    #ax.legend().set_visible(False)
    plt.ylim((0.0, 1500.0))
    plt.show()

看起来是空值导致了问题


  def user_params
    params.permit(
      :id, :name, :email, :username, :country, :avatar, :id_number, :license_number
    ).select {|x,v| v.present?}
  end

我的模型

 "id_number"=>"234545", "license_number"=>"234545", "avatar"=>""