嵌套表单:find_or_create_by多个字段

时间:2012-02-11 10:43:10

标签: ruby-on-rails ruby activerecord associations nested-forms

我陷入了嵌套表单的中间并使用了活动记录“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

我的表单如下所示:app / views / transactions / 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)

但我应该在哪里使用它,它应该如何看待?

我真的很感谢你的帮助!

1 个答案:

答案 0 :(得分:0)

您可以使用Category.find_or_initialize_by_title_and_account_id(category.title, account.id),然后修改并保存(_create_将对象保存在同一行中)。但如果我理解正确,你需要的是validations。按照惯例,我们设计我们的应用程序以在控制器的#create操作中检索错误(例如:“类别标题必须唯一”),如果有错误,我们再次render :action => :new(使用相同的格式以前,但显示错误)。我看到你正在使用formtastic,所以默认情况下你会在表单中显示错误(我认为)。