在类之外访问实例变量 - Ruby

时间:2016-02-17 14:38:45

标签: ruby ruby-on-rails-4

我已经看过很多关于这个话题的帖子,并且因为我无法将它们用于我的例子而道歉但我似乎可以让它工作

如果数据存在

,我有一个可以预填充用户信息的表单
def new
  BraintreeTransaction::PopulateForm.new(@user).populate_form
end

module BraintreeTransaction
  class PopulateForm
    def initialize(user)
      @user = user
    end

    def populate_form
     return if Transaction.where(user_id: @user.id, completed: false).empty?
     user_details = Transaction.where(user_id: @user.id, completed: false).order(created_at: :desc).first
     @first_name = user_details.first_name if user_details.first_name.present?
     @last_name = user_details.last_name if user_details.last_name.present?
   end
end

我的表格

<%= text_field_tag :first_name, @first_name, placeholder: 'First Name', required: true %>
<%= text_field_tag :last_name, @last_name, placeholder: 'Last Name', required: true %>

在这种情况下如何访问实例变量?

由于

1 个答案:

答案 0 :(得分:2)

这里的简单答案是添加attr_reader,使这些变量可以访问:

class BraintreeTransaction::PopulateForm
  attr_reader :first_name
  attr_reader :last_name

  # ...
end

然后,只有在捕获填充模块时才能访问这些:

def new
  @populate = BraintreeTransaction::PopulateForm.new(@user).populate_form
end

在您的视图中,您可以像这样使用它们:

<%= text_field_tag :first_name, @populate.first_name, ... %>

我建议这样做,但要避免手动初始化:

class BraintreeTransaction::PopulateForm
  def initialize(user)
    @user = user
  end

  def first_name
    user_details and user_details.first_name
  end

  def last_name
    user_details and user_details.last_name
  end

  def user_details
    @user_details ||=
      Transaction.where(
        user_id: @user.id,
        completed: false
      ).order(
        created_at: :desc
      ).first
end

这样可以将查询减少一半并缓存结果,因此只有第一次访问才有成本。手动调用populate_form是隐含的,不再需要。