RAILS 4 - 如何在索引视图中显示NAME而不是ID?

时间:2014-07-11 05:56:27

标签: ruby-on-rails

在这里绑新手。 我希望我的问题/ view / index显示与问题相关的语言的名称,而不是language_id。

我的问题模型是:

class Question < ActiveRecord::Base
  validates :phrase, presence: true
  has_many :answers, dependent: :delete_all
  belongs_to :language
end

class CreateQuestions < ActiveRecord::Migration
  def change
    create_table :questions do |t|
      t.string :phrase
      t.string :language

      t.timestamps
    end
  end
end

class AddLanguageIdToQuestions < ActiveRecord::Migration
  def change
    add_column :questions, :language_id, :integer
  end
end

我的语言模型是:

class Language < ActiveRecord::Base
end

class CreateLanguages < ActiveRecord::Migration
  def change
    create_table :languages do |t|
      t.string :name

      t.timestamps
    end
  end
end

在我的问题控制器中:

def index
  @questions = Question.all
  @language = Language.find(@questions.language_id)
end

在问题/ _form.html.erb中:

<p>
  <%= f.label :language_id %><br>
  <%= f.select :language_id, @languages.map { |l| [l.name, l.id] }, {:prompt => 'select language'} %>
</p> 

在questions / view / index.html.erb中:

<% @questions.each do |question| %>
    <li>"<%= link_to question.phrase, question %>" in <%= question.language.name %>?%></li>
<% end %>

我不断得到的错误,尽管尝试了几个“question.language.name”的变体(在show视图中工作得很好)是索引视图中的“undefined method”language_id“。

非常感谢任何帮助。

3 个答案:

答案 0 :(得分:1)

只需将您的索引操作更改为:

def index
  @questions = Question.all.includes(:language)
end

修改

<% @questions.each do |question| %>
    <% unless question.language.nil? %>
    <li>"<%= link_to question.phrase, question %>" in <%= question.language.name %>?%></li>  <% end %>
<% end %>

OR

<% @questions.each do |question| %>
    <li>"<%= link_to question.phrase, question %>" in <%= question.language.name unless question.language.nil? %>?%></li>
<% end %>

两者都可以正常工作取决于你想要什么。

随时问问问题是否继续解决。

您的问题

你做错了是:

找到所有问题然后这一行错误地找到了所有问题的语言。

  @language = Language.find(@questions.language_id)

要避免这种情况:更好的解决方案是使用includes

避免N + 1查询问题

答案 1 :(得分:1)

ActiveRecord Associations

这听起来像是ActiveRecord协会的工作,特别是the has_many association

enter image description here

ActiveRecord关联基本上使用数据库中的foreign_key来提取关系数据&amp;附加到您的对象。目前,您只专注于使用单个对象,而没有任何关联数据。

-

您可以使用以下方法解决问题:

#app/models/question.rb
Class Question < ActiveRecord::Base
   belongs_to :language
end

#app/models/language.rb
Class Language < ActiveRecord::Base
   has_many :questions
end

这将允许您在控制器中调用以下内容;视图:

#app/controllers/questions_controller.rb
Class QuestionsController < ApplicationController
   def index
       @questions = Question.all
   end
end

#app/views/questions/index.html.erb
<% @questions.each do |question| %>
   <%= question.language.name %>
<% end %>

-

<强>加成

您可以使用.delegate方法为您提供停止law of dementer问题的功能:

#app/models/question.rb
Class Question < ActiveRecord::Base
   belongs_to :language
   delegate :name, to: :language, prefix: true #-> @question.language_name
end

答案 2 :(得分:0)

@questions.language_id不正确,因为您尝试从数组中检索单个ID。即Question.all返回一个数组。此外,Language.find需要一个id参数才能返回单一语言。

你究竟想用Language.find(@questions.language_id)回归什么?一系列具有属于它的问题的语言?

此外,_form.html.erb部分在哪里调用?默认情况下,rails scaffold将调用new和edit操作中的partial,因此如果您尝试为partial表单中的select字段设置@languages,那么您不会在索引操作中执行此操作。另外,请考虑对此字段使用collection select作为关联。