Rails 4:使用验证分离模型和控制器功能

时间:2016-05-06 13:12:48

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

我试图将一些逻辑与我的控制器分开,但却无法按照我喜欢的方式运行。我的控制器中有一个函数,它接受一个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"

1 个答案:

答案 0 :(得分:1)

您可以在模型或控制器中执行此操作。这是大多数开发人员对可重用性的看法所做的设计决策:用户授权是否是模型的一般用途?如果您想重新使用您的模型,您是否需要相同的授权方案?

如果将其放入模型中,WeighIn模型应该可以访问用户模型或授权模型。然后导入函数可以返回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 %>