因此,我有一些从 Controller 中的另一个 Rails 应用程序中提取的数据,我们将其称为“ExampleController”,我想在允许向导移动到下一步之前验证它是否存在于我的模型中,但我不能完全做到这一点弄清楚我应该如何做(我知道直接从 Controller 获取这些数据到模型中违反了 MVC,我正在寻找从 Controller 获取数据的最佳解决方法)。数据必须来自 Controller ,因为获取数据的方法包含在 ApplicationController 中,但是如果更容易的话,我可以在 Awizard Controller 中执行此操作。 (而且我不能使用 gem )
请针对问题提供某种建议,而不是解释为什么这不是做我已经意识到但无法以其他方式做的事情的正确方法。
<小时/>示例 Controller
这应该渲染数据然后检查它在其他地方不是空白吗?
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?示例 Controller 中的方法?在我的验证中。
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
<小时/>
或者我需要将其添加到此 View 中吗?
(/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 对于应用程序来说是全局的,并且 @wizard 实例将依赖于全局状态,因此封装得很差。但是来自另一个站点的数据在您的应用范围内全局存在。因此,巫师作为持有数据的人并没有不匹配。相反,它可以被视为一个特征。
举一个例子。巫师的魔法只有在满月时才有效。 应用程序SkyReport发送数据:
:full_moon => true
如果他们需要继续其力量的第二步,它会影响第一阶段的所有巫师。因此,依赖 Wizard.valid_data?
的全局状态正是我们想要的......
但是如果每个向导都有来自甘道夫应用程序的个人消息,那么我们将希望强制调用甘道夫的数据,但解决方案甚至更简单:
# 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(的一些情况),并且从问题的呈现方式来看,来自其他站点的数据是相当不可知的!
这里的问题是我们对应用程序、其要求和底层逻辑了解不够,无法决定什么是好是坏......
关于ruby-on-rails - 如何在模型中验证来自 Controller 的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14309688/