1

私は何か愚かなことを見落としていることを願っています、そしてあなたの助けに前もって感謝します、私はレールに非常に新しく、マイケル・ハートルによるレールチュートリアルブックを完成させました、そして私は足場なしで物事をするために働いています。

経費にはそれぞれExpenseTypeがあります...(1 =食事、2 =航空運賃など)。整数をtype_idとして経費テーブルに保存しています。私の見解では、実際のExpenseTypeの名前フィールドの値を表示したいと思います。

エラーは(そして、なぜ失敗するのかがはっきりとわかります。経費テーブルにexpense_id列がありません....しかし、どの接続が欠落しているかわかりません。

SQLite3::SQLException: no such column: expense_types.expense_id: SELECT  "expense_types".* FROM "expense_types"  WHERE "expense_types"."expense_id" = 14 LIMIT 1

より明示的な外部キー参照を提供する必要があると思いますが、それを行に含めようとしても役に立ちませんでした。


モデル

class Expense < ActiveRecord::Base
  attr_accessible :amount, :expense_date, :description, :is_billable, :mileage, 
                                :pay_method, :project_id, :type_id

  belongs_to :project
  has_one :expense_type

  validates :expense_date, presence: true
  validates :type_id, presence: true
  validates :project_id, presence: true  
  validates :amount, presence: true, numericality: { greater_than: 0 }

end

およびExpenseTypeモデル

class ExpenseType < ActiveRecord::Base
  attr_accessible :name, :active

  belongs_to :expense

  validates :name, presence: true

end

私のコントローラー

class ExpensesController < ApplicationController

def index
  @expense = Expense.new
  @expense_list = Expense.all

  # UI options
  @button_text = 'New' 
  @button_type = 'primary'   

end

def new
end

def create
  @expense = Expense.new(params[:expense])
  @expense_list = Expense.all

  # UI options
  @button_text = 'New' 
  @button_type = 'primary'   

  if @expense.save
    #sign_in @expense
    flash[:success] = "You have added an expense."
      redirect_to :back
  else
      render 'index'
  end

end

def edit
  @expense = Expense.find(params[:id])
  @expense_list = Expense.all

  # UI options
  @button_text = 'Save' 
  @button_type = 'success'   

  render 'index'
end

def update
  @expense = Expense.find(params[:id])
  @expense_list = Expense.all  
  if @expense.update_attributes(params[:expense])
    flash[:success] = "Updated"
    #sign_in @expense
    redirect_to :back
  else
    render 'index'
  end
end

def destroy
  @expense = Expense.find(params[:id])
  @expense.destroy
  flash[:success] = "expense deleted"
  redirect_to :back
end


end

そして最後にビュー

<% provide(:title, 'Expenses') %>
<h1>Manage Expenses</h1>

<div class="row">
  <div class="span11 well"> 
    <%= form_for @expense do |f| %>
    <%= render 'shared/error_messages', object: f.object %>    

    <div class="row">   


          <div class="span4">
            <%= f.label :project_id %>
            <%= f.text_field :project_id, class: "span4" %>
          </div>  


    </div>
    <div class="row">   

          <div class="span2">
            <%= f.label :expense_date, "Date" %>
            <%= f.text_field :expense_date, class: "span2", value: "03/04/2012" %>
          </div>


          <div class="span3">
            <%= f.label :type_id %>
            <%= collection_select(:expense, :type_id, ExpenseType.all, 
                    :id, :name, { prompt: 'Select Expense Type'}, { class: 'span3' }) %>
          </div>  

          <div class="span1">
            <%= f.label :amount %>
            <%= f.text_field :amount, class: "span1" %>
          </div>          

          <div class="span1">
            <%= f.label :mileage %>
            <%= f.text_field :mileage, class: "span1" %>
          </div>  
          <div class="span1">
            <%= f.label :is_billable, "Billable?" %>
            <%= f.text_field :is_billable, class: "span1" %>
          </div>                        
           <div class="span2">
            <%= f.label :pay_method %>
            <%= f.text_field :pay_method, class: "span2" %>
          </div>          


    </div>
    <div class="row">   
          <div class="span4">
            <%= f.label :description %>
            <%= f.text_area :description, rows: 2, class: "span4" %>
          </div>

          <div class="span3">
            <%= f.label :description, "Attendees" %>
            <%= f.text_area :description, rows: 2, class: "span3" %>
          </div>
         <div class="span2">
           <BR> <%= f.submit "    #{@button_text}    ", class: "btn btn-large btn-#{@button_type}" %>
          </div>

    </div>    
    <% end %>
  </div>
</div>



<div class="row">
  <div class="span12">
     <table class="table table-bordered table-striped">
       <thead>
        <tr>
          <th>Date</th>
          <th>Project</th>
          <th>Type</th>
          <th>Amount</th>         
          <th>Description</th>  
        </tr> 
       </thead>
       <tbody>
       <% @expense_list.each do |expense_item| %>

       <tr>
          <td><%= expense_item.expense_date %></td>
          <td><%= expense_item.project_id %></td>         
          <td><%= expense_item.type_id %></td>         
          <td><%= expense_item.amount %></td>
          <td><%= expense_item.description %></td>

          <td><%= link_to 'Edit', edit_expense_path(expense_item[:id]) %></td>
          <td><%= link_to 'Delete', expense_item, method: :delete, data: { confirm: 'Are you sure?' } %></td>
        </tr>
        <% end %> 
      </tbody>  
    </table>

  </div>
</div>

...私が取り組んでいるセクションは後半部分で、わかりやすくするためにここに再度貼り付けています

<% @expense_list.each do |expense_item| %>

          .....

<%= expense_item.expense_type.name %>

          ......
        <% end %> 
4

1 に答える 1

0

モデルの関連付けで FK を指定します。また、ここでは has_one ではなく、belongs_to 関係を使用する必要があるようです

has_one は、経費オブジェクトへの変更は、経費タイプ レコードも変更する必要があることを意味します (変更する必要があるわけではなく、慣例によります)。

has_one を使用する場合は、次のことを行う必要があります。

has_one :expense_type, primary_key: :type_id

属している場合:

belongs_to :expense_type, foreign_key: :type_id

コードを ExpenseType で構造化する必要があると私が感じる方法に基づいて、次のものが必要です。

has_many :expenses, foreign_key: :type_id
于 2012-07-22T20:53:46.257 に答える