Search code examples
ruby-on-railsarraysformsselectmodels

Rails: array created in one model, reach in from form in another


I've got a form view of an Order model (orders_form.html.erb) with a select option:

<%= f.select :pay_type, PaymentType.array_of_payment_types,
             :prompt => 'Select a payment method' %>

PaymentType is another model and .array_of_payment_types is an array created out of the entries in the payment_type_name column, like so:

def self.array_of_payment_types
  @array_of_payment_types ||= PaymentType.pluck(:pay_type_name)
end

... from models\payment_type.rb

But I get a proc 'empty?' error:

undefined method `empty?' for #

I hope my problem is clear, it seems like there is an obvious solution but I haven't found one reading other questions so far...

I will update with the relationships in the models...

My models:

payment_type.rb:

class PaymentType < ActiveRecord::Base
  attr_accessible :pay_type_name

  has_many :orders

  validates :pay_type_name, :uniqueness

  def self.names
    all.collect { |pt| pt.pay_type_name }
  end 

  def self.array_of_payment_types
    PaymentType.all.map{ |p| [p.pay_type_name, p.id] }
  end
end

order.rb:

class Order < ActiveRecord::Base
  attr_accessible :address, :email, :name, :pay_type, :payment_type_id, :cart_id, 
                  :product_id

  has_many :line_items, :dependent => :destroy
  belongs_to :payment_type

  #PAYMENT_TYPES = ['Check','Purchase order','Credit card']

  validates :name, :address, :email, :presence => true
  validates  :pay_type,
             :presence => true,
             :inclusion => { :in => proc { PaymentType.array_of_payment_types } }

  def add_line_items_from_cart(cart)
    cart.line_items.each do |item|
      item.cart_id = nil
      line_items << item
    end
  end
end

Solution

  • Try using the options_for_select:

    # in the view:
    <%= f.select :pay_type, options_for_select(PaymentType.array_of_payment_types),
             :prompt => 'Select a payment method' %>
    
    # in the PaymentType model:
    def self.array_of_payment_types
      PaymentType.all.map{ |p| [p.pay_type_name, p.id] }
    end
    

    You also need to update your validates statement in the Order model:

    validates  :pay_type,
               :presence => true,
               :inclusion => { :in => proc { PaymentType.pluck(:pay_type_name) } }