Search code examples
ruby-on-railsjbuilder

rails: undefined method for ActiveRecord_Relation with Jbuilder


I have a model named RequestForm that I want to render the seed data in my sample web interface.

The structure of this model looks like this:

table:

create_table "request_forms", force: :cascade do |t|
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.date "request_date"
    t.string "submit_by"
    t.string "submit_to"
    t.string "requester_name"
end

Seed Data:

RequestForm.delete_all

RequestForm.create! (
  [
    {
      requester_name: "David",
      request_date: Date.new(2017,1,2)
    },
    {
      requester_name: "Mike",
      request_date: Date.new(2018,1,3)
    },
    {
      requester_name: "Jack",
      request_date: Date.new(2018,1,3)
    }
  ]
)

The Controller looks like this:

class Api::RequestFormsController < ApplicationController
  def show
    @RequestForm = RequestForm.find(param[:id])
  end

  def index
    @RequestForms = RequestForm.all
  end
end

It is resourced in the routes.rb as well

namespace :api, defaults: { format: :json } do
      resources :request_forms, only: [ :index, :show ]
end

When i tried to create a jbuilder file with a single line:

json.extract! @RequestForms, :requester_name, :request_date

That's where the 500(internal server error) occur. I clicked into the error message and it said:

undefined method `requester_name' for #<RequestForm::ActiveRecord_Relation:0x00007f2c0a879f28>

I dont know why it is expecting a relation since from the document in the link here: http://www.rubydoc.info/github/rails/jbuilder/Jbuilder:extract!

Extracts the mentioned attributes or hash elements from the passed object and turns them into attributes of the JSON.

I am simply following the example it provided. So what did i do wrong here?


Solution

  • Since you're using @RequestForms in your jbuilder template, I'm assuming you're trying to render the index action.

    json.extract! @RequestForms, :requester_name, :request_date
    

    In this case, @RequestForms is a RequestForm::ActiveRecord_Relation, not a RequestForm object. I think what you're looking for is json.array! to help you render the collection of objects you have.

    For example, you could do something like this:

    json.array! @RequestForms do |request_form|
      json.requester_name request_form.requester_name
      json.request_date request_form.request_date
    end
    

    Although, the code you have is pretty close to working. Instead of json.extract! you can simply use json.array! to extract attributes from the array directly.

    json.array! @RequestForms, :requester_name, :request_date
    

    The official jbuilder documentation shows this technique like this:

    # @people = People.all
    
    json.array! @people, :id, :name
    
    # => [ { "id": 1, "name": "David" }, { "id": 2, "name": "Jamie" } ]