Search code examples
ruby-on-railsrubyattributesattr-accessor

attr_accessor vs attributes one failing the other


I'm using her gem in my rails app to get data from a web service backend instead of a database. This question isn't completely related to the gem though is what I believe.

My model is using ActiveModel

class Merchant

  include ActiveModel::Model

  # Add the awesomeness of Her gem
  include Her::Model

  attr_accessor :name, :type

  validates :name, presence: true

end

and my controller is

  def create

    @merchant = Merchant.new(params[:merchant])
    if @merchant.valid?
      respond_to do |format|
        if @merchant.save
          format.html { redirect_to @merchant, notice: 'Merchant was successfully created.' }
          format.json { render :show, status: :created, location: @merchant }
        else
          format.html { render :new }
          format.json { render json: @merchant.errors, status: :unprocessable_entity }
        end
      end
    else
     render :new
   end
  end

I have a form in my view like this

<%= form_for(@merchant) do |f| %>
  <%= f.label :name, "First Name" %>
  <%= f.text_field :name %>

  <%= f.label :type, "Type" %>
  <%= f.text_field :type %>

  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

Now here the attr_accessor :name, :type is needed inside the model for the form to function properly or its throwing this error

undefined method `name' for #<Merchant(merchants) >

If i add the attr_accessor in the Model then @merchant.attributes is returning {}.

and this leads to the gem sending blank request to server because the gem uses attributes to build the request. I checked in the source of the gem.

If i don't add attr_accessor then everything works fine except the form throws error.

What is way to fix this error. I'd be honest i don't clearly understand how attributes work.


Solution

  • The code suggests that if @merchant has an attribute called name, this won't happen:

    class Merchant
    
      include ActiveModel::Model
    
      # Add the awesomeness of Her gem
      include Her::Model
    
      attributes :name, :type
    
      validates :name, presence: true
    
    end