加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

ruby-on-rails – 如何在模型中验证来自控制器的数据

发布时间:2020-12-16 20:58:05 所属栏目:百科 来源:网络整理
导读:所以我有一些数据从控制器中的另一个rails应用程序中拉出来让我们称之为ExampleController,我想在我的模型中验证它,然后才允许向导进入下一步,我无法弄清楚如何我应该这样做(我知道直接从控制器获取这些数据到模型中违反了MVC我正在寻找从控制器获取数据的最
所以我有一些数据从控制器中的另一个rails应用程序中拉出来让我们称之为ExampleController,我想在我的模型中验证它,然后才允许向导进入下一步,我无法弄清楚如何我应该这样做(我知道直接从控制器获取这些数据到模型中违反了MVC我正在寻找从控制器获取数据的最佳解决方法).数据必须来自控制器,因为获取它的方法包含在ApplicationController中,但如果这更容易,我可以在Awizard控制器中执行此操作. (我也不能用宝石)

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

示例控制器

这应该代替渲染数据,然后检查它在其他地方是不是空白?

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)

我如何使用valid_data?来自示例控制器的方法?在我的验证中.

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

或者我需要将此添加到此视图中吗?

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

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

解决方法

我可能误解了这个问题,因为我的答案很简单.然而,这里的解决方案并不依赖于元编程,而是指向Wizard(类不是它创建的对象)是一个单例/常量.
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.

更新:关于全球状态问题的推理

(由@Valery Kvon提出)

该论点是,向导是应用程序的全局,并且@wizard实例将依赖于全局状态,因此被严重封装.但是来自其他网站的数据在您的应用范围内非常普遍.因此,与持有数据的人没有不匹配.相反,它可以被视为一个特征.

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

:full_moon => true

如果他们需要继续执行他们的第二步,它会影响第一阶段的所有向导.因此依赖于Wizard.valid_data的全局状态?正是我们想要的……

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

# 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以及如何呈现问题,来自另一个站点的数据是非常不可知的!

这里的问题是我们对应用程序及其要求和基本逻辑的了解不足以决定什么是好的……

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读