【问题标题】:Accessing a variable in the body of a class访问类主体中的变量
【发布时间】:2019-12-20 17:16:54
【问题描述】:

我正在尝试使用Muffin 在我的应用程序中实现表单对象。

在我的控制器中,我这样做:

class MyController < ApplicationController
  def new
    @form = MyForm.new
  end
end

其中MyForm 是一个表单对象,如下所示:

class MyForm < Muffin::Base
  attribute :my_attribute
end

我想做的基本上是这样的:

class MyController < ApplicationController
  def new
    @form = MyForm.new(array_of_attribute_names)
  end
end

这样在实例化MyForm 时,我可以按照以下方式进行操作:

class MyForm < Muffin::Base
  array_of_attribute_names.each do |name|
    attribute name
  end
end

我知道上面的方法是行不通的,它暴露了对 Ruby 的 OO 模型缺乏理解。有什么办法可以达到同等效果吗?

【问题讨论】:

标签: ruby-on-rails ruby oop


【解决方案1】:

您可以重载初始化方法。这样的东西应该可以工作,但您可能需要调整参数结构以适应 Muffin 基类:

class MyForm < Muffin::Base
  def initialize(options = {})
    if options[:array_of_attribute_names].present?
      options[:array_of_attribute_names].each do |attribute_name|
        attribute attribute_name
      end
    end
    super
  end
end

然后:

@form = MyForm.new(array_of_attribute_names: array_of_attribute_names)

【讨论】:

  • def initialize(options = [])会不会容易一点? (OP似乎没有表明除了array_of_attribute_names之外的任何东西都会被传入。)如果坚持传入的哈希值,你不能做if options[:array_of_attribute_names] - 这将是nil或不是?如果传入一个数组,你不能完全取消if 条件吗?
  • 这样也行。我只是使用选项哈希约定。我只是想 OP 可以使用该键并将数组作为值传递。
  • 感谢您的回答,不幸的是这不起作用 - 请参阅我对 jvillian 回答的评论。
【解决方案2】:

只是重复 NM Pennypacker 提供的答案...

如果你想做:

@form = MyForm.new(array_of_attribute_names: array_of_attribute_names)

那么看来你可以这样做:

class MyForm < Muffin::Base
  def initialize(options={})
    class_eval do 
      options[:array_of_attribute_names].each do |attribute_name|
        attribute attribute_name
      end if options[:array_of_attribute_names]
    end
    super
  end
end

如果你想坚持你在问题中概述的方式:

@form = MyForm.new(array_of_attribute_names)

那么看来你可以这样做:

class MyForm < Muffin::Base
  def initialize(options=[])
    class_eval do 
      options.each do |attribute_name|
        attribute attribute_name
      end
    end
    super
  end
end

【讨论】:

  • 感谢您的回答。不幸的是,当我尝试这个时,我得到一个undefined method 'attribute' for #&lt;MyForm:0x00007f9f88550530&gt; 错误。我认为那是因为#attributedefined 作为类方法,这使得它在MyFormClass 的一个实例)上可用,但在MyForm 的任何实例上都不可用。我可以在这种情况下以某种方式访问​​此方法吗?
  • 我担心使用 class_eval 意味着我又回到了原点,因为我现在可以访问该方法,但我不再拥有 options 哈希可供我使用。
  • 我不知道“我不再拥有选项哈希”是什么意思。请多说。毕竟,您可以简单地将其分配给一个实例变量,然后就可以使用了。除了原始问题中描述的选项之外,您还希望对这些选项做什么?
猜你喜欢
  • 2015-12-07
  • 1970-01-01
  • 1970-01-01
  • 2015-06-10
  • 1970-01-01
  • 2021-04-16
  • 2021-08-09
  • 2011-08-28
  • 1970-01-01
相关资源
最近更新 更多