2012-02-11 87 views
0

我被困在嵌套形式和活動記錄使用中間的「find_or_create_by」方法..我試圖做的事:嵌套形式:find_or_create_by多個字段

我有3種型號:帳戶,交易和類別。

class Account < ActiveRecord::Base 
    has_many :transactions, :dependent => :destroy 
    has_many :categories, :dependent => :destroy 
end 

class Category < ActiveRecord::Base 
    has_many :transactions 
    belongs_to :account 
end 

class Transaction < ActiveRecord::Base  
    belongs_to :category, :autosave => true 
    belongs_to :account 

    accepts_nested_attributes_for :category 
end 

我的形式是這樣的:應用程序/視圖/交易/ new.haml

= semantic_form_for @transaction do |f| 
    = f.inputs do 
    = f.input :account_id, :as => :hidden 
    = f.input :title, :label => false 
    = f.input :amount, :label => false 
    = f.inputs :for => :category do |c| 
     = c.input :title, :as => :string 
     = c.input :account_id, :as => :hidden 
    = f.buttons do 
    = f.submit "Save" 

我的控制器是這樣的:

class TransactionsController < ApplicationController 

    def new 
    @transaction = Transaction.new 
    @transaction.date ||= Transaction.last.date if Transaction.last 
    @transaction.account= Account.find(params[:account]) if params[:account] 
    @account = @last_transaction.account if @last_transaction 
    @account = Account.find(params[:account]) if params[:account] 
    @transaction.build_category(:account => @account) 
    end 

    def create 
    @transaction = Transaction.new(params[:transaction]) 
    @account = @transaction.account 
    respond_to do |format| 
     if @transaction.save 
     format.html {redirect_to (new_transaction_path(:account => @account))} 
     else 
     format.html {redirect_to (new_transaction_path(:account => @account))} 
     end 
    end 
    end 
end 

類別控制器:

class CategoriesController < ApplicationController 

    before_filter :authenticate_user! 

    def new 
    @category = Category.new 
    @category.account = Account.find(params[:account]) if params[:account] 
    @accounts = current_user.accounts 
    end 

    def create 
    @category = Category.new(params[:category]) 
    respond_to do |format| 
     if @category.save 
     format.html {redirect_to (categories_path)} 
     else 
     format.html {render :action => "new"} 
     end 
    end 
    end 

    def update 
    @category = Category.find(params[:id]) 
    respond_to do |format| 
     if @category.update_attributes(params[:category]) 
     format.html {redirect_to (categories_path)} 
     else 
     format.html {render :action => "edit"} 
     end 
    end 
    end 
end 

現在,我卡住了。我只想創建一個新類別,如果還沒有一個具有相同標題和相同account_id的現有類別。

現在,它總是創建一個新的類別,忽略已經有一個具有相同名稱和相同account_id的類別。我知道,我應該使用這樣的事情:

Category.find_or_create_by_title_and_account_id(category.title, account.id) 

但我應該在哪裏使用它,它應該如何看到底是什麼?

我真的很感謝你的幫忙!

+0

那麼你的控制器代碼在哪裏? – fl00r 2012-02-11 10:53:10

+0

我添加了控制器代碼。 – algi 2012-02-11 11:01:37

回答

0

您可以使用Category.find_or_initialize_by_title_and_account_id(category.title, account.id),然後修改它並保存(_create_保存在同一行中的對象)。但如果我理解正確,你需要的是validations。按照慣例,我們設計我們的應用程序來檢索控制器的#create動作中的錯誤(如:「類別標題必須是唯一的」),如果有錯誤,我們再次render :action => :new(具有與先前相同的形式,但顯示錯誤)。我發現你使用的是formtastic,所以你默認情況下會在窗體中顯示錯誤(我認爲)。

+0

感謝您的回答。但是,我會在哪裏放置你的建議線?哪個控制器和哪個動作? – algi 2012-02-11 17:54:16

+0

您在控制器中擁有它,因爲這是通常和最合適的方式。我發現你的代碼存在一些問題,你有沒有閱讀rails guide?你的控制器中'@ last_transaction'的定義在哪裏? – farnoy 2012-02-11 19:28:56

+0

你可以嘗試用'@transaction.category = Category.find_or_initialize_by_account_id_and_transaction_id(@ account.id,@ transaction.id)替換'@ transaction.build_category(:account => @account)'' – farnoy 2012-02-11 19:34:28