Search code examples
ruby-on-railsrubyviewmodelserb

Displaying associated data in rails (user_id, email, etc)


I've found a few posts about this but nothing that I've tried to work with has done it for me so far. I'm still pretty fresh to rails - I'm basically solid with HTML and CSS, but I took the Skillshare Rails class and I'm working on combining that with the Railstutorial book. So please be gentle.

I have a basic app, with users that can create 'items.' I used scaffolding to get 'items' up. They might as well be microposts. But with the views that scaffolding creates, I wanted to display the email address of the user instead of the email address. What would I change in the model, view, and controller? Here's what I've got.

controller:

def email
  @email = @item.user_id.email
end

view:

<td><%= item.content %></td>
<td><%= @email %></td>
<td><%= link_to 'Show', item %></td>
<td><%= link_to 'Edit', edit_item_path(item) %></td>
<td><%= link_to 'Destroy', item, confirm: 'Are you sure?', method: :delete %></td>

item model:

class Item < ActiveRecord::Base
  attr_accessible :content, :user_id
  validates :content, :length => { :maximum => 140 }
  belongs_to :user
end

user model:

class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :token_authenticatable, :confirmable,
  # :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
     :recoverable, :rememberable, :trackable, :validatable

  # Setup accessible (or protected) attributes for your model
  attr_accessible :email, :password, :password_confirmation, :remember_me
  has_many :items
end

Solution

  • There Are Three ways to this.

    First, The Best way I feel. As per your requirement is simple delegation.

    class Item < ActiveRecord::Base
      attr_accessible :content, :user_id
      validates :content, :length => { :maximum => 140 }
      belongs_to :user
    
      delegate :email, to: :user
    end
    

    In Views,

    Simply call.

    <td><%= item.email %></td>
    

    Like @cluster said

    you can use in controller

    @email = @item.user.email
    

    Or

    Move the code to Item Model

    class Item < ActiveRecord::Base
      attr_accessible :content, :user_id
      validates :content, :length => { :maximum => 140 }
      belongs_to :user
    
      def user_email
        user.email
      end
    end
    

    In views,

    <td><%= item.user_email %></td>