从连接表中列出视图

时间:2016-01-31 00:09:36

标签: ruby-on-rails postgresql foreign-keys jointable

如图所示,has_many已加入数据库

class Address < ActiveRecord::Base
  has_many :years, dependent: :destroy
  has_many :people, through: :years 
end

class Year < ActiveRecord::Base
  belongs_to :address
  belongs_to :person
end

class Person < ActiveRecord::Base
  has_many :years, dependent: :destroy
  has_many :addresses, through: :years    
end

我在列表视图中遇到问题,即Views>Years>list.html.erb

以下是不起作用的示例:

# table headers here
<% @years.each do |y| %>
   <tr>
     <td><%= y.year_date %></td>
     <td><%= y.person_id %></td>
     <td><%= y.person.given_name %></td>
     <td><%= y.person.last_name %></td>
    ...
<% end %>

year_date是该人在地址处的日期,如果given_namelast_name行不存在,则显示正常。 year.person_id显示也很好。 但year.person.given_nameyear.person.last_name不会显示。 given_namelast_name是Person表中的字段。

错误为undefined method given_name for nil:NilClass

显然有点像菜鸟或者这会更明显。部分问题可能在于如何对搜索进行短语。

此处填写完整代码:https://bitbucket.org/MtnBiker/crores5

感谢您的建议。一直在寻找。

编辑:环顾四周开始想知道外键,这里是我通过pgAdmin在数据库中找到的内容。

ALTER TABLE people
  ADD CONSTRAINT fk_rails_56c79562d9 FOREIGN KEY (address_id)
      REFERENCES addresses (id) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION;

编辑2.添加控制器:

class YearsController < ApplicationController
  helper_method :sort_column, :sort_direction
  before_action :set_year, only: [:show, :edit, :update, :destroy]

  def index
    @years = Year.all
    @years = Year.order(sort_column + " " + sort_direction)
  end

模式?

CREATE TABLE years
(
  id serial NOT NULL,
  year_date date,
  created_at timestamp without time zone NOT NULL,
  updated_at timestamp without time zone NOT NULL,
  resto boolean,
  resid boolean,
  source text,
  person_id integer,
  address_id integer,
  title character varying,
  CONSTRAINT years_pkey PRIMARY KEY (id),
  CONSTRAINT fk_rails_8fc1813509 FOREIGN KEY (person_id)
      REFERENCES people (id) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION,
  CONSTRAINT fk_rails_e1624dbb3f FOREIGN KEY (address_id)
      REFERENCES addresses (id) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION
)
WITH (
  OIDS=FALSE
);
ALTER TABLE years
  OWNER TO gscar;

-- Index: index_years_on_address_id

-- DROP INDEX index_years_on_address_id;

CREATE INDEX index_years_on_address_id
  ON years
  USING btree
  (address_id);

-- Index: index_years_on_person_id

-- DROP INDEX index_years_on_person_id;

CREATE INDEX index_years_on_person_id
  ON years
  USING btree
  (person_id);

编辑:在这个漫长(抱歉)的讨论结束时给出答案。

2 个答案:

答案 0 :(得分:0)

undefined method given_name for nil:NilClass

这意味着您在未定义的变量上调用given_name。在您的情况下,person.given_name

问题是要么您没有关联的person对象(IE它不存在),或者关联设置不正确。

-

调试的几个步骤:

  1. 是否填充了person_id
  2. 您的架构是否设置正确?
  3. 最可能的问题是您的person_idforeign key)值不存在。您可以使用rails console来测试该值是否存在,从而看到这一点:

    $ rails c
    $ years = Year.all
    $ years.each do |year|
    $ - year.person_id
    $ end
    $ -> output of person_id values
    

    如果您没有person_id的值,则表示您的Year无法与相应的Person相关联(因此您的问题)。要解决此问题,您需要确保数据库中存在respective foreign keys & objects

    #app/models/year.rb
    class Year < ActiveRecord::Base
       belongs_to :address
       belongs_to :person
    
       validates :person, :address, presence: true
    end  
    

    -

      

    开始想知道外键

    这似乎不是问题(我检查了您的迁移):

    enter image description here

    以上显示has_many :through所需的唯一外键应为address_id&amp; person_id模型中的Year。除非foreign_keyModel,否则您在表格中不需要belongs_to

    <强>更新

    修复方法是使用.try

    #app/views/years/index.html.erb
    ...
      <%= y.person.try(:given_name) %>
    

答案 1 :(得分:0)

Rich Peck想出了一个解决方案。它应该已经发布,这意味着存在一个潜在的问题,我希望能够及时找到OP;特别是因为在尝试修复它的过程中,他找到了很多东西需要修复。

解决方法是使用method try<td><%= y.person.given_name %></td>替换为<td><%= y.person.try(:given_name)</td>。没有其他任何改变。

谢谢Rich。