如图所示,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_name
和last_name
行不存在,则显示正常。
year.person_id
显示也很好。
但year.person.given_name
和year.person.last_name
不会显示。 given_name
和last_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);
编辑:在这个漫长(抱歉)的讨论结束时给出答案。
答案 0 :(得分:0)
undefined method given_name for nil:NilClass
这意味着您在未定义的变量上调用given_name
。在您的情况下,person.given_name
问题是要么您没有关联的person
对象(IE它不存在),或者关联设置不正确。
-
调试的几个步骤:
person_id
?最可能的问题是您的person_id
(foreign 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
-
开始想知道外键
这似乎不是问题(我检查了您的迁移):
以上显示has_many :through
所需的唯一外键应为address_id
&amp; person_id
模型中的Year
。除非foreign_key
有Model
,否则您在表格中不需要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。