8

我有两种型号UserSubmission如下:

class User < ActiveRecord::Base
  # Associations
  has_many :submissions
  accepts_nested_attributes_for :submissions

  # Setup accessible (or protected) attributes for your model
  attr_accessible :email, :name, :role, :submission_ids, :quotation_ids, :submissions_attributes

  validates :email, :presence => {:message => "Please enter a valid email address" }
  validates :email, :uniqueness => { :case_sensitive => false }
end

class Submission < ActiveRecord::Base
  belongs_to :user
  attr_accessible :due_date, :text, :title, :word_count, :work_type, :rush, :user, :notes

  validates :work_type, :title, :text,:presence => true
  validates :text, :length => { :minimum => 250 }
  validates :word_count, :numericality => { :only_integer => true }
end

我有一个表格来收集这两个模型所需的数据。用户控制器:

def index
  @user = User.new
  @user.submissions.build
end

def create
  @user = User.where(:email => params[:user][:email]).first_or_create(params[:user])

  if @user
    redirect_to :root
  else
    render 'pages/index'
  end
end

我要做的是首先通过提交的电子邮件检查用户是否已经存在于系统中。如果是这样,那么我想为该用户创建一个提交。否则同时创建用户和提交。

我对如何使用该first_or_create方法执行此操作感到困惑。

任何帮助表示赞赏。

4

3 回答 3

13

first_or_create accepts a block. So you could do it as follows:

@user = User.where(:email => params[:user][:email]).first_or_create do |user|
  # This block is called with a new user object with only :email set
  # Customize this object to your will
  user.attributes = params[:user]
  # After this, first_or_create will call user.create, so you don't have to
end
于 2013-05-24T03:00:29.660 回答
2

由于您的用例稍微复杂一些,因此将其拆分为两个单独的操作可能没有什么坏处。如果您希望这以原子方式发生,您可以将其放入事务中。

User.transaction do
  # Create the user if they don't already exist
  @user = User.where(:email => params[:user][:email]).first_or_create

  # Update with more attributes, and create nested submissions
  @user.update_attributes(params[:user])
end
于 2013-05-23T04:24:18.860 回答
-3

嘿,我认为应该是这样的

@user = User.first_or_create(params[:user])

然后在用户模型中

def first_or_create(params)
  unless user = User.where(:email => params[:email]).first # try to find user
    user = User.create(email: params[:user]) 
    # it should create also submission because of accepts_nested_attributes_for 
  else #user exsists so we need to create submission for him
    user.submissions.create(params[:submissions])
  end
end
于 2013-05-20T11:25:11.227 回答