ThalesMiguel
ThalesMiguel

Reputation: 194

Ruby on Rails - getting association data

I´m trying to make a User - Infos association where my User has_many Infos.

I´m trying to call my User Infos on the index form from Users.

By calling <%= user.infos %> on my index.html.erb (Users) it returns me all datas from the Infos table like this:

[#<Info id: 2, name: "Thales Miguel", date: "1989-07-14", area: "An\xC3\xA1lise de Sistemas", comment: "Analista j\xC3\xBAnior de sistemas.", user_id: 1, created_at: "2012-01-16 15:54:29", updated_at: "2012-01-16 15:54:29">]

I assumed that by doing <%= user.infos.comment %> it would return me the "comment" from that user, but all I get is this error:

undefined method `comment' for #<ActiveRecord::Relation:0x3b8ebe8>

What am I doing wrong?

infos_controller:

class InfosController < ApplicationController

  def create
    @user = User.find(params[:user_id])
    @info = @user.infos.create(params[:info])
    redirect_to user_path(@user)
  end

  def destroy
    @user = User.find(params[:user_id])
    @info = @user.infos.find(params[:id])
    @info.destroy
    redirect_to user_path(@user)
  end

  def new
    @user = User.new
    @user.build_info    
end

end

info model:

class Info < ActiveRecord::Base
  belongs_to :user
end

user model:

class User < ActiveRecord::Base
  validates :login,    :presence => true
  validates :password, :presence => true,
                       :length   => {:minimum => 5}

  has_many :infos, :dependent => :destroy

end

Upvotes: 0

Views: 2571

Answers (4)

Gabor Garami
Gabor Garami

Reputation: 1265

So, collecting all info what written above:

You cannot call user.infos.comment, because the return value of user.infos is an ActiveRecord::Relation in Rails 3.2 and an array in Rails 3.1 and below. Neither ActiveRecord::Relation nor array do not know what it should do with comment method because they don't know anything of the contained objects.

You have multiple solutions for solve this problem.

If user is limited to have only one info:

class User < ActiveRecord::Base
  has_one :info, :dependent => :destroy
end

<%= user.info.comment %>

If user can have multiple info objects:

<%- user.infos.each do |info| %>
<%= info.comment %>
<% end -%>

Or

<ul><li>
<%= user.infos.collect(&:comment).join('</li><li>').html_safe %>
</li></ul>

Or if you want to display only the first info:

<%= user.infos.any? ? user.infos.first.comment : "N/A" %>

Be careful the latest solution: user.infos never be nil, but user.infos.first can be nil, so you must check available infos with user.infos.any?

Upvotes: 2

vicosanz
vicosanz

Reputation: 57

The problem is

info is a relationship link

that returns an array of info records, if you want to show the first one for example

user.infos[0].comment

or

user.infos.first.comment

if that user don't have infos then return nil

Upvotes: 1

Marco
Marco

Reputation: 106

You should do this way:

<% user.infos.each do |info| %>
  <%= info.comment %>
<% end %>

As davidb said, <% user.infos %> returns an array. The object of .comment should be an instance.

Upvotes: 1

davidb
davidb

Reputation: 8954

This:

[#<Info id: 2, name: "Thales Miguel", date: "1989-07-14", area: "An\xC3\xA1lise de Sistemas", comment: "Analista j\xC3\xBAnior de sistemas.", user_id: 1, created_at: "2012-01-16 15:54:29", updated_at: "2012-01-16 15:54:29">]

is an array. You have to choose one of the objects. You can't call an attribute value without selecting one of theses objects. Okay, in this case there is only one object but that doesn't matter.

Upvotes: 2

Related Questions