Search code examples
ruby-on-railsrubyactiverecordactivemodelrails-models

I wanna use model attribute in view Rails


I am trying to use attribute value in model but its not working.. I have three models:

models/resident.rb

class Resident < ActiveRecord::Base
  belongs_to :hostel
  has_one :user,dependent: :delete
end

models/user.rb

class User < ActiveRecord::Base
 belongs_to:resident
end

models/hostel.rb

class Hostel < ActiveRecord::Base
  has_many :residents
  has_one :rate_card,dependent: :delete
end

Schema

Resident

create_table "residents", force: :cascade do |t|
    t.string   "room_number"
    t.string   "roll_number"
    t.string   "name"
    t.datetime "created_at",  null: false
    t.datetime "updated_at",  null: false
    t.integer  "hostel_id"
  end

User

create_table "users", force: :cascade do |t|
    t.string   "roll_number"
    t.string   "email"
    t.datetime "created_at",                        null: false
    t.datetime "updated_at",                        null: false
    t.integer  "resident_id"
  end

Hostel

create_table "hostels", force: :cascade do |t|
    t.string   "hostel"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

Now i want to use the hostel attribute value in users/show.html.erb I am able to do this :

<%if @user.resident.roll_number=="101303110"%>

if the roll number is present then returning true.. but if is use :

<%if @user.resident.hostel=="J"%>

and if J is a hostel present in Hostel model then it is returning false.

But when we put<%@user.resident.hostel%> in show.html.erb then it is showing value J. How should I use related models attributes in each other view?


Solution

  • Given your associations, @user.resident.hostel would load a hostel. But you want to compare the hostel string on the hostel. Therefore your comparison should be:

    <% if @user.resident.hostel.hostel == 'J' %>
    

    Explanation:

    @user                         # returns your a user
    
    @user.resident                # follows `belongs_to :resident` and 
                                  # returns a resident
    
    @user.resident.hostel         # follows `belongs_to :hostel` on the resident and
                                  # returns a hostel
    
    @user.resident.hostel.hostel  # returns the value store in the `hostel`
                                  # column of that `hostel`
    

    Btw. I would argue that chaining calls like that violates the Law of Demeter. But it is hard to suggest any alternative without having more insights into your app.