Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/heroku/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 如何在模型中验证来自控制器的数据_Ruby On Rails_Forms_Validation_Model View Controller_Activemodel - Fatal编程技术网

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

Ruby on rails 如何在模型中验证来自控制器的数据,ruby-on-rails,forms,validation,model-view-controller,activemodel,Ruby On Rails,Forms,Validation,Model View Controller,Activemodel,因此,我有一些数据是从控制器中的另一个rails应用程序中提取的,我们称之为ExampleController,我想在允许向导进入下一步之前验证它是否存在于我的模型中,我不太明白应该如何做(我知道直接从控制器获取数据到模型中违反了MVC,我正在寻找从控制器获取数据的最佳解决方法)。数据必须来自控制器,因为获取数据的方法包含在ApplicationController中,但是如果更简单,我可以在Awizard控制器中执行此操作。(此外,我不能使用gem) 请针对这个问题提供一些建议,而不是解释为什

因此,我有一些数据是从控制器中的另一个rails应用程序中提取的,我们称之为ExampleController,我想在允许向导进入下一步之前验证它是否存在于我的模型中,我不太明白应该如何做(我知道直接从控制器获取数据到模型中违反了MVC,我正在寻找从控制器获取数据的最佳解决方法)。数据必须来自控制器,因为获取数据的方法包含在ApplicationController中,但是如果更简单,我可以在Awizard控制器中执行此操作。(此外,我不能使用gem)

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


示例控制器

class AwizardController < ApplicationController

  def valid_data
    data = #data from elsewhere
    if !data.blank?
      Awizard.valid_data = true
    else
      Awizard.valid_data = false
  end

end
这是否应该呈现数据,然后检查它在其他地方是否为空

class ExampleController < ApplicationController

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

end

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

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



#这是我想要验证的步骤


您可以将控制器中的数据作为参数传递给模型中的验证方法

在您的模型中/awizard.rb

def valid_for_step_one?(some_external_data)
  #validation logic here
end
class Awizard
  include ActiveModel::Validations

  cattr_accessor :valid_data

  validate :data_validation :if => lambda { |o| o.current_step == "step1" }

  def data_validation
    if self.valid_data == false || self.valid_data.blank?
      errors.add(:valid_data, "not found")
    end
  end

  #Other wizard stuff

end
因此,在控制器中,您可以调用:

model.valid_for_step_one?(data_from_controller)
如果你能描述一下你从控制器获得的数据,那也很好。它与模型awizard有什么关系


因为另一个选项是将外部数据设置为模型的属性。然后您可以在验证函数中使用它。

与模型共享控制器级数据的唯一方法是通过外部访问器。 使用元编程,可以巧妙地将其传递给模型实例

控制器
我可能误解了这个问题,因为我的答案很简单。然而,这里有一个解决方案,它不求助于元编程,而是因为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
如果第1阶段的所有向导需要继续第2步的操作,它会影响他们。因此,依赖于
向导的全局状态。有效的\u数据?
正是我们想要的

但是,如果每个向导都有一条来自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有所了解,从问题的表现来看,来自另一个站点的数据是相当不可知的


这里的问题是,我们对应用程序、其要求和基本逻辑了解不够,无法决定什么是好的或不好的…

因此,我尝试编辑并添加到@charlysisto问题中,因为这是最接近答案的问题,但它不起作用,因此我使用了以下解决方案,因为答案是将数据从控制器发送到t模型(尽管答案没有使用视图调用控制器方法)这里是我的解决方案

模型-模型/awizard.rb

def valid_for_step_one?(some_external_data)
  #validation logic here
end
class Awizard
  include ActiveModel::Validations

  cattr_accessor :valid_data

  validate :data_validation :if => lambda { |o| o.current_step == "step1" }

  def data_validation
    if self.valid_data == false || self.valid_data.blank?
      errors.add(:valid_data, "not found")
    end
  end

  #Other wizard stuff

end
查看-awizard/_step1.html.erb

<div class="field">
  <% f.label "valid data? %>
  <% @_controller.valid_data %> #Call controller method to send data to model
</div>


我觉得你可以把这个问题简化一点。但你永远不应该(不能)从模型中调用一个控制器方法。为什么这个方法在控制器中?我想你会从显示实际代码中受益。从你在这里显示的内容中我可以看出,我只是将控制器方法移动到模型中。你也可以检查是的,我以前尝试过简化,但我得到的答案并没有真正得到我想要的正在尝试这样做。我无法将实际代码显示为工作代码。我可以尝试将该方法移动到模型中,但不确定它是否仍然可以从其他rails应用程序中获取数据。无法将gem用于向导,但将查看代码,看我是否可以获得任何提示。感谢您的建议。(是的,我确实对控制器模型感到好奇)因此,我尝试将我的方法从控制器移动到该方法,但问题是它需要应用程序_controller.rb中的各种东西。我真的在寻找一种方法,在我的模型中获取这些数据,即使它必须被赋予一个路由,即example/data.json并从那里获取?+1代表@99miles关于从中调用控制器方法的注释在一个模型中。如果验证定义了模型,那么代码应该在模型中。这似乎是你在与框架抗争,这可能是你沮丧的根源。你试图实现什么?我必须有逻辑来请求控制器中的数据基本上是我的问题我意识到获取dat模型中控制器的a违反了MVC,但我无法移动它,因此我正在寻找最优雅的方法来检查模型中的数据基本上来自控制器。您好,感谢这个答案,这有很多优点,尽管@charlysisto有一个更好的解决方案,我相信。错误。因为当您对类本身进行处理时,它会在应用程序的所有请求之间共享验证数据。在我的解决方案中,您实现了特殊的单例方法,并且验证数据仅对当前请求是唯一的。很抱歉,您还需要进一步讨论一下,您能给我一个使用建议答案可能会出现的问题的示例吗?顺便问一下每个模型,即
Awizard
,对于应用程序中的各种向导都是唯一的,即
class TestWizard
,因为向导的步骤需要加载到该模型中。或者您正在谈论控制器?因为这对向导也是唯一的。向导类是一个通用的、应用程序范围内的常量。您可以赋值(验证数据)到类级属性(实际上是变量),因为该类的所有其他调用及其所有实例都将看到这些数据。现在,假设您发送请求并获取有效数据为“false”,
class Awizard
  include ActiveModel::Validations

  cattr_accessor :valid_data

  validate :data_validation :if => lambda { |o| o.current_step == "step1" }

  def data_validation
    if self.valid_data == false || self.valid_data.blank?
      errors.add(:valid_data, "not found")
    end
  end

  #Other wizard stuff

end
<div class="field">
  <% f.label "valid data? %>
  <% @_controller.valid_data %> #Call controller method to send data to model
</div>
class AwizardController < ApplicationController

  def valid_data
    data = #data from elsewhere
    if !data.blank?
      Awizard.valid_data = true
    else
      Awizard.valid_data = false
  end

end