Domanda

I am having trouble accessing an a related model's attributes by a foreign key.

Each user has many applications Each application belongs to one school

When I try to show the school_name attribute in the users dashboard (user#show), I get a undefined method error for school_name

The application has a user_id and a school_id, which should serve as foreign keys. I was thinking there might be a problem with this, but couldn't find documentation.

I can call @application.school_id and it will return the correct integer value, but related attributes on the school table are irretrievable.

Any help would be much appreciated.

Users controller

class UsersController < ApplicationController
  before_filter :authenticate_user!

  def show
    @user = current_user
    @applications = @user.applications :include => [:school_name]

  end
end

User Model

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


  has_many :applications 
  has_many :editors, :through => :applications
  has_and_belongs_to_many :schools 
end

User/show.html.erb

<div class="hero-unit">
<center><h1> Hello <%= @user.name %></h1></center>

<%= link_to "New Application", new_application_path %>

<h2>
    Current Applications
</h2>


<%@applications.each do |app|%>
<%= app.school_name %>
<%end%>





</div>

Application Model

require 'carrierwave'
class Application < ActiveRecord::Base
    mount_uploader :app_file, ImageUploader
    belongs_to :user, :class_name => User, :foreign_key => "user_id"
    belongs_to :school, :class_name => School, :foreign_key => "school_id"
    belongs_to :editor
    end
È stato utile?

Soluzione 2

Change

<%= app.school_name %>

to

<%= app.school.school_name %>

Here's how associations work:

If user has many applications and each application belongs to a school, you can retrieve applications from the user object:

user.applications

and the school for each application via:

application.school 

school, here, is the whole object. To retrieve underlying attributes, you'll have to query those from the school object and not application

Altri suggerimenti

For the application to be able to call school_name directly like that you have to tell it where to look with a delegate call. Otherwise (as in the other answer) you have to spell out the association path. I'm going to steer clear of the whole Law of Demeter angle (apart from that mention) and just say that delegation can be quite convenient when a call to an associated model's attribute happens frequently.

Eg

class Application
  belongs_to :school, :class_name => School, :foreign_key => "school_id"
  delegate :school_name, :to => :school
  ...
end

Has the effect that calling .school_name on an Application is treated as .school.school_name

Shouldn't school_name be school.name?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top