0

RoRに関しては非常に環境に配慮しており、問題の原因がモデルの関連付けの問題なのか、データへのアクセスに正しい構文を使用していないのかを判断するのに苦労しています。

ユーザーは多くの予算を持つことができます。各予算は、複数の詳細行で構成されています。予算に取り込まれているため、budget_detailsのユーザーIDは必要ないと思いました。したがって、3つの関係から推測できます(多分?!)

Budget_detailsインデックスに、ユーザー名を含めることができるようにしたいと思います。'show'ビューで機能しますが、インデックスでは機能しません。

私はこれらをセットアップするために足場を使用しました、それで私はそこにたくさんのクラッドがあることを知っています、私は実際にそれをするために新しいプロジェクトに移る前にただ例をしようとしていました。

実際のエラーは次のとおりです。

NoMethodError in Budget_details#index

Showing C:/Sites/example1/app/views/budget_details/index.html.erb where line #17 raised:

undefined method `name' for nil:NilClass

これが失敗する理由がわかりませんが、showメソッドは機能しますか?スコープと関係がありますか?つまり、showはシングルインスタンスレベルですが、indexは「all」レベルであるため、Usersでデータを見つけることができませんか?

どんな助けでも大歓迎

モデル:

User.rb

class User < ActiveRecord::Base
attr_accessible :email, :name

has_many :budgets
has_many :budget_details, :through => :budgets

Budget.rb

class Budget < ActiveRecord::Base
attr_accessible :budget_name, :user_id

belongs_to :user
has_many :budget_details

Budget_details.rb

class BudgetDetail < ActiveRecord::Base
attr_accessible :amount, :amount_type, :budget_id, :itemname

belongs_to :budget

コントローラー-budget_details_controller.rb

class BudgetDetailsController < ApplicationController
# GET /budget_details
# GET /budget_details.json
def index
  @budget_details = BudgetDetail.all
  @users = User.all

    respond_to do |format|
    format.html # index.html.erb
    format.json { render json: @budget_details }
  end
end

# GET /budget_details/1
# GET /budget_details/1.json
def show
  @budget_detail = BudgetDetail.find(params[:id])
  @user = User.find(params[:id])

  respond_to do |format|
    format.html # show.html.erb
    format.json { render json: @budget_detail }
  end
end
.....

show.html.erb <%=通知%>

<p>
  <b>Username:</b>
  <%= @user.name %>
</p>

<p>
  <b>Budget:</b>
  <%= @budget_detail.budget_id %>
</p>

<p>
  <b>Itemname:</b>
  <%= @budget_detail.itemname %>
</p>

<p>
  <b>Amount:</b>
  <%= @budget_detail.amount %>
</p>

<p>
  <b>Amount type:</b>
  <%= @budget_detail.amount_type %>
</p>
<%= link_to 'Edit', edit_budget_detail_path(@budget_detail) %> |
<%= link_to 'Back', budget_details_path %>

index.html.erb

<h1>Listing budget_details</h1>

<table>
  <tr>
    <th>Username</th>
    <th>Itemname</th>
    <th>Budget</th>
    <th>Amount</th>
    <th>Amount type</th>
    <th></th>
    <th></th>
    <th></th>
  </tr>

<% @budget_details.each do |budget_detail| %>
  <tr>
    <td><%= @user.name %></td>
    <td><%= budget_detail.itemname %></td>
    <td><%= budget_detail.budget_id %></td>
    <td><%= budget_detail.amount %></td>
    <td><%= budget_detail.amount_type %></td>
    <td><%= link_to 'Show', budget_detail %></td>
    <td><%= link_to 'Edit', edit_budget_detail_path(budget_detail) %></td>
    <td><%= link_to 'Destroy', budget_detail, method: :delete, data: { confirm: 'Are    you sure?' } %></td>
  </tr>
<% end %>
</table>

<br />
4

2 に答える 2

1

ファイルindex.html.erb内:

<td><%= @user.name %></td>

アクションで定義@userしていないため、エラーが発生します。index

アソシエーションを使用するだけで、この問題を回避し@user、いずれかのアクションでコントローラーを直接プルすることができます。

<td><%= budget_detail.user.name %></td>

そして、そうすることによるパフォーマンスの低下(N + 1)を回避するために、以下を使用してコントローラーにそれらを熱心にロードすることができますincludes

@budget_details = BudgetDetail.includes(:user).all

ただし、この関連付けはまだ存在していません。クラスに「has-one-through」関係を追加する必要があります。BudgetDetailこれは、クラスに対して行ったのとは逆ですUser

has_one :user, :through => :budget

要約すると

'has-one-through'としてuserアソシエーションを追加する必要があります。BudgetDetail

コントローラのアクションは次のようになります。

def index
  @budget_details = BudgetDetail.includes(:user).all

  respond_to do |format|
    format.html # index.html.erb
    format.json { render json: @budget_details }
  end
end

def show
  @budget_detail = BudgetDetail.find(params[:id])

  respond_to do |format|
    format.html # show.html.erb
    format.json { render json: @budget_detail }
  end
end

@user.nameそして、あなたの見解では、むしろ使用しないでください:

<%= budget_detail.user.name %>
于 2013-01-24T20:15:50.153 に答える
1

error は、nilで@user.nameあるためエラーであることを示します。@user

あなたのコントローラーでは、現在フェッチしているようです:

def index
  @budget_details = BudgetDetail.all
  @users = User.all 
end    

def show
  @budget_detail = BudgetDetail.find(params[:id])
  @user = User.find(params[:id]) # THIS WOULD MEAN THAT A USER HAS THE SAME ID AS THE BUDGET_DETAIL
end

index アクションが index テンプレートの変数を取得すると、そこには何も取得していないことがわかります。すべてのユーザーを保持する変数@userだけを取得しています。@users

代わりに、両方のアクションでユーザー フェッチを削除し、budget_detail.user関連付けを介してビューでそれらをフェッチする必要があります。

def index
  @budget_details = BudgetDetail.all
end    

def show
  @budget_detail = BudgetDetail.find(params[:id])
end

show.html.erb

<p>
  <b>Username:</b>
  <%= @budget_detail.user.name %>
</p>

<% @budget_details.each do |budget_detail| %>
  <tr>
    <td><%= budget_detail.user.name %></td>
    ...
  </tr>
<% end %>
于 2013-01-24T20:18:58.470 に答える