【问题标题】:Rails 4: Separate model and controller functions with validationsRails 4:使用验证分离模型和控制器功能
【发布时间】:2016-09-01 14:02:29
【问题描述】:

我试图从我的控制器中分离出一些逻辑,但无法让它按照我想要的方式工作。我的控制器中有一个函数,它接受一个 CSV 文件并将每一行输入到我的 WeighIns 表中:

# Controller (WeighIn belongs_to User)

def bulk_upload_weigh_ins
    import = WeighIn.import(params[:file])
    redirect_to import_weigh_ins_path, notice: "Weigh Ins Imported Successfully!"
end

然后我的模型中有 CSV 解析功能

# WeighIn model    

def self.import(file)
    CSV.foreach(file.path, headers: true) do |row|
        hashed_row = row.to_hash
        # VALIDATE HERE
        WeighIn.create hashed_row
    end
end

但在 WeighIns 表中创建条目之前,我想确保哈希中有一个属性对应的用户,即User.find_by(scale_id: hashed_row["scale_id"]) != nil 其中scale_id 是我的User 上的行和列的一部分表。

我如何验证这一点并返回一个有用的错误,告诉我“没有用户使用 scale_id: Foo”

【问题讨论】:

    标签: ruby-on-rails validation csv model-view-controller


    【解决方案1】:

    您可以在模型或控制器中执行此操作。这是大多数开发人员根据他们对可重用性的看法做出的设计决策:用户授权是您模型的通用目的吗?如果您想重复使用您的模型,您想要相同的授权方案吗?

    如果将其放入模型中,WeighIn 模型应该可以访问 User 模型或授权模型。然后导入函数可以返回 true 以表示成功。

    在控制器中,您可以使用您已经指出的条件来实现授权,或者更一般地,使用“before_action”回调可以在调用实际函数之前检查授权,例如

    before_action :check_authorization, only: [:bulk_upload_weigh_ins]
    
    private
      def check_autorization
        render nothing:true, status: :forbidden unless (autorized_condition)
      end
    

    在这两种情况下,您可能希望通过使用“render nothing:true, status: :forbidden”来返回 http 禁止响应 (403),或者通过呈现带有错误消息的布局来返回更复杂的 html 响应。在这里,“flash”通常会出现,您可以在“WeighIn/bulk_upload_weigh_ins.html.erb”(或 haml)模板中使用它(参见 The Flash)。

    flash[:alert] = "You are wrong!"
    

    现在,在您的操作中,要么什么都不做(渲染操作的默认模板)、渲染一个特殊模板或重定向用户(如果您使用 before_action 停止处理,则必须完成其中之一)。

    render 'an_error_template'  # in views/controller/an_error_template.html.erb or haml
    
    redirect_to :other_action # sends the browser to another action, flash[:alert] is still accessible there
    

    记得在你的布局或动作模板中查询 flash 以显示类似的消息

    <% flash.each do |message_type, message| %>
      <%= content_tag(:div, message, class: "alert alert-#{message_type}") %>
    <% end %>
    

    【讨论】:

    • 感谢您如此详细的回复,我一定会把这些步骤落实到位。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-27
    相关资源
    最近更新 更多