如何在模型中验证来自控制器的数据 [英] How to validate in a model, data from a controller

查看:129
本文介绍了如何在模型中验证来自控制器的数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,我有一些数据是从控制器中的另一个Rails应用程序中提取的,可以将其称为ExampleController,我想在允许向导继续进行下一步之前验证它是否存在于模型中,我不能弄清楚我应该怎么做(我知道直接将数据从控制器中导入模型会违反MVC,我正在寻找从控制器中获取数据的最佳解决方法).数据必须来自控制器,因为获取数据的方法包含在ApplicationController中,但是如果这样更容易的话,我可以在Awizard控制器中进行操作. (我也不能使用宝石)

So I have some data that gets pulled from another rails app in a controller lets call it ExampleController and I want to validate it as being there in my model before allowing the wizard to move to its next step and I can't quite figure out how I should be doing it (I know that getting this data directly from the controller into the model violates MVC I am looking for the best workaround to get my data from the controller) . The data must come from the controller as the methods for getting it are contained in ApplicationController however I could do this in the Awizard controller if this is easier. (Also I cannot use a gem)

请提供一些有关该问题的建议,而不是解释为什么这不是我已经意识到但不能以另一种方式做事的正确方法.

示例控制器

这应该呈现数据,然后检查其他地方是否为空白吗?

should this instead render the data then check it isn't blank elsewhere?

class ExampleController < ApplicationController

  def valid_data?            
    data = #data could be nil or not
    if data.blank?
      return false
    else
      return true
  end

end


我的模型-(models/awizard.rb)

如何使用有效数据?示例控制器的方法?在我的验证中.

How do I use the valid_data? method from the example controller? in my validation here.

class AWizard
include ActiveModel::Validations
include ActiveModel::Conversion
include ActiveModel::Dirty
include ActiveModel::Naming

#This class is used to manage the wizard steps using ActiveModel (not ActiveRecord)

attr_accessor :id
attr_writer :current_step  #used to write to current step
define_attribute_methods [:current_step] #used for marking change

validate :first_step_data, :if => lambda { |o| o.current_step == "step1" };

def first_step_data
  #What should i put here to check the valid_data? from the examplecontroller
end

def initialize(attributes = {})
   attributes.each do |name, value|
     send("#{name}=", value)
   end
end

def current_step
  @current_step || steps.first
end

def steps
  %w[step1 step2 step3] #make list of steps (partials)
end

def next_step
  current_step_will_change! #mark changed when moving stepped
  self.current_step = steps[steps.index(current_step)+1] unless last_step?
end

def previous_step
  current_step_will_change! #mark changed when moving stepped
  self.current_step = steps[steps.index(current_step)-1] unless first_step?
end

def first_step?
  current_step == steps.first
end

def last_step?
  current_step == steps.last
end

def all_valid?
  steps.all? do |step|
    self.current_step = step
    valid?
  end
end

def step(val)
  current_step_will_change!
  self.current_step = steps[val]
end

def persisted?
  self.id == 1
end

end


还是我需要将此添加到此视图?


Or do I need to add this to this view?

(/views/awizard/_step1.html.erb)

<div class="field">
  <%= f.label 'Step1' %><br />
  #This is the step I want to validate
</div>


推荐答案

由于我的回答很简单,我可能误解了这个问题.但是,这里的解决方案不是求助于元编程,而是基于向导(类不是它创建的对象)是单例/常量的事实.

I maybe have misunderstood the question since my answer is simple. However here's a solution that doesn't resort to metaprogramming, but to the fact that Wizard (the class not objects it creates ) is a singleton/constant.

class ExampleController < ApplicationController

  def valid_data?            
    data = #data could be nil or not
    result = data.blank?
    Awizard.valid_data= result
    result
  end

end

class Wizard
  cattr_accessor :valid_data


  def valid_data?
    self.class.valid_data
  end
end

如果在使用向导传递step_one之前必须已经调用了ExampleController#valid_data课程.

If course ExampleController#valid_data must have been called before you play around with a Wizard passing step_one.

(由@Valery Kvon提出)

(raised by @Valery Kvon)

参数是向导对于应用程序是全局的,并且@wizard实例将依赖于全局状态,因此被错误地封装.但是来自另一个站点的数据 在您的应用程序范围内很遗憾.因此,与向导蜜蜂保持数据的人没有任何不匹配.相反,它可以被认为是一个特征.

The argument is that Wizard is global to the application and that @wizard instances will be dependant on a global state and are therefore badly encapsulated. But Data, coming from another site, is gloabl in the scope of your app. So there's no mismatch with Wizard beeing the one holding the data. On the contrary it can be considered as a feature.

一个例子.奇才魔术只有在满月时才有效. 应用程序SkyReport发送数据:

One example. Wizards magic is only efficient at full moon. Application SkyReport sends data :

:full_moon => true

如果第1阶段的所有向导需要继续执行其功能的第2步,它就会受到影响.因此,正是我们想要的是依靠Wizard.valid_data?的全局状态.

It affects all wizards in stage 1 if they need to go on step2 of their power. Therefore relying on the global state of Wizard.valid_data? is exactly what we want...

但是如果每个向导都有一条来自Gandalf应用程序的个人消息,那么我们想强制调用Gandalf的数据,但是解决方案甚至更简单:

However if each wizard has a personal message coming from Gandalf's application, then we'll want to inforce the invocation of Gandalf's data but then the solution is even simpler :

# in example_controller.rb
before_filter :set_wizard_data, :only => [:create, :update]
....
def set_wizard_data
  @wizard = Wizard.find params[:id]
  @wizard.valid_data= valid_data
end

但这再次意味着Gandalf.app知道@wizard(的知识),并且通过问题的表现方式,来自另一个站点的数据是不可知的!

But this again implies that Gandalf.app knows (something of) the @wizard and from how the problem is presented, data coming from the other site is pretty agnostic !

这里的问题是,我们对应用程序,其要求以及确定优劣的基本逻辑了解不足...

The issue here is that we don't know enough about the app, its requirements and underlying logic to decide what's good or not...

这篇关于如何在模型中验证来自控制器的数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆