user1876508
user1876508

Reputation: 13172

How can I pass in a variable defined in a class into a Rails form?

If I have a controller

class MyController < ApplicationController
  vals = [...]

  def new
    ...
  end

  def create
    if save
      ...
    else
      render 'new'
    end
  end

how can I make the "vals" variable accessible to both methods? In my "new" view I want to use the "vals" variable for a drop-down menu, but rails is giving me errors. Of course, I could just copy the variable twice, but this solution is inelegant.

Upvotes: 0

Views: 80

Answers (4)

Myxoh
Myxoh

Reputation: 73

A different way from the ones before (although probably just having the instance method is preferred as in Sebastian's solution) is, take advantage of the fact that functions and local variables are called in the same way in ruby and just write:

 def vals
   @vals ||= [...]
 end

and you should be able to access it on the controllers (not the views). If you want it on your views as well you can call at the beginning of the controller

 helper_method :vals

If you want to be able to modify vals using vals="some value"

def vals= vals_value
  @vals = vals_value
end

Take into account that probably using the intance variable as in Sebastian's solution is preferred, but if you, for whatever reason, are settled on being able to call "vals" instead of "@vals" on the view (for example if you are using send or try), then this should be able to do it for you.

Upvotes: 1

Sachin R
Sachin R

Reputation: 11876

Define in corresponding model

Eg :

class User < ActiveRecord::Base

  TYPES = %w{ type1 type2 type3 }

end

and use in ur form like

User::TYPES

=> ["type1", "type2", "type3"]

You can reuse this anywhere in the application.

Upvotes: -1

John Hayes-Reed
John Hayes-Reed

Reputation: 1438

As Sebastion mentions a before_ hook / callback is one way to go about it, however as you mentioned it is for a dropdown menu, I am guessing it is a non-changing list, if so I would suggest perhaps using a Constant to define the values, perhaps in the model they are specific to, or if it is to be used in many places a PORO would do nicely to keep things DRY. This will then also allow you to easily access it anywhere, for example in models for a validation check, or to set the options of the dropdown menu in the view, or in the controller if you so wish:

class ExampleModel
  DROPDOWN_VALUES = [...].freeze

  validates :some_attr, inclusion: { in: DROPDOWN_VALUES } 
end

class SomeController < ApplicationController
  def new
    # can call ExampleModel::DROPDOWN_VALUES here
  end

  def create
    # also here, anywhere actually
  end
end

Upvotes: 2

Sebasti&#225;n Palma
Sebasti&#225;n Palma

Reputation: 33491

You could use a before_* callback, e.g a before_action, this way you sets your vals variable as an instance one and make it to be available for your both new and create methods, something like:

class SomeController < ApplicationController
  before_action :set_vals, only: [:new, :create]

  def new
    ...
    # @vals is available here
  end

  def create
    if save
      ...
      # and here
    else
      render 'new'
    end
  end

  private 

  def set_vals
    @vals = [...]
  end
end

Upvotes: 2

Related Questions