2016-02-17 4 views
0

Я видел довольно много постов на эту тему, и прошу прощения за не будучи в состоянии использовать их для моего примера, но я могу показаться, чтобы заставить его работатьдоступа Переменные экземпляра вне класса - Рубин

У меня есть форма, могут быть предварительно заполнены информацией пользователей, если данные exisits

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 %> 

Как получить доступ к переменной экземпляра в этой ситуации?

Благодаря

+0

Вы имеете в виду '@ user'? Вам нужно и accessor, например 'attr_reader: user' (или вручную определить' def user; @user end') – brito

+0

вы могли бы объяснить, почему '@ user'? – Richlewis

+0

В вашем названии упоминается доступ к «переменной экземпляра класса», а '@ user' - это переменная экземпляра, поэтому я предположил, что вы спрашиваете, как получить доступ к ней за пределами« PopulateForm ». Если я сделал неправильное предположение, дайте мне знать. – brito

ответ

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 вручную подразумевается, больше не требуется.

+0

Вау, это отличный ответ и очень прост для вас, спасибо – Richlewis

+0

не могли бы вы объяснить метод 'user_details', пожалуйста, в основном' @user_details || = 'спасибо – Richlewis

+0

также я заметил, что вы пропустили класс, а не модуль > класс .. это лучшая практика? мне не нужно объявлять модуль? – Richlewis

Смежные вопросы