【问题标题】:List view from join table连接表的列表视图
【发布时间】:2016-05-08 14:53:26
【问题描述】:

如图所示的 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

我在使用 Years 的列表视图时遇到问题,即 Views&gt;Years&gt;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);

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

【问题讨论】:

  • 请在您的问题中包含您的相关架构和控制器。
  • 我写了一篇文章,但没有真正的解决方案;如有必要,我会删除,但更重要的是,如果我们跳进聊天以对其进行排序会更好。如果您发表评论,我们可以修复它
  • 也可能是插值问题
  • 丰富。这边没聊过,不知道怎么实现。私人或有渠道。看起来像8小时的时间差异。因此可能是明天早上我的时间。 -8 格林威治标准时间

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


【解决方案1】:
undefined method given_name for nil:NilClass

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

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

--

调试的几个步骤:

  1. person_id 是否已填充?
  2. 您的架构设置正确吗?

最可能的问题是您的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 所需的唯一外键应该是Year 模型中的address_idperson_id。除非Model 具有belongs_to,否则您不需要在表中使用foreign_key


更新

解决方法是使用.try:

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

【讨论】:

  • 您建议的控制台测试的部分输出 > [#, #
  • 所以它似乎在拉数据。即使使用上面的代码,您确定它不起作用吗?
  • 以下是浏览器中显示的内容:nil:NilClass 的未定义方法 `given_name' 提取的源代码(第 35 行附近): 如果我注释掉最后一行,浏览器部分显示:!Page displays correctly and ID is 52 再次感谢您的帮助。我知道这是一件被忽视的小事。我会像现在一样推高我的代码。 PS对不起,这里的时间限制让我明白了。
  • 您确定given_name 存在于各自的记录中吗?
  • 我进行了 rake 测试。这是一个似乎相关的错误。这些测试是由 Rails 生成的。我还没准备好写测试。下一步。 ::的ActionView模板::错误:::的ActionView模板::错误:未定义的方法given_name' for nil:NilClass app/views/years/show.html.erb:32:in _app_views_years_show_html_erb__969981829392708727_70138521098720' 测试/控制器/ years_controller_test.rb:28:在block in &lt;class:YearsControllerTest&gt;' app/views/years/show.html.erb:32:in _app_views_years_show_html_erb__969981829392708727_70138521098720' 跨度>
【解决方案2】:

Rich Peck 想出了一个变通办法。它应该像发布的那样工作,这意味着存在一个潜在的问题,我是 OP,希望能及时发现;特别是因为在尝试修复它的过程中,他发现了很多要修复的东西。

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

谢谢你。

【讨论】:

    猜你喜欢
    • 2020-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多