尝试在Active Record中实现create if else else update记录。
目前正在使用:
@student = Student.where(:user_id => current_user.id).first
if @student
Student.destroy_all(:user_id => current_user.id)
end
Student = Student.new(:user_id => current_user.id, :department => 1
)
Student.save!
如果记录存在或者创建记录,更新记录的正确方法是什么?
答案 0 :(得分:59)
在Rails 4中
Student.
find_or_initialize_by(:user_id => current_user.id).
update_attributes!(:department => 1)
答案 1 :(得分:15)
::first_or_create
(自v3.2.1开始提供)执行它在框中所说的内容。
Model.where(find: 'find_value').
first_or_create(create: 'create_value')
# If a record with {find: 'find_value'} already exists:
before #=> #<Model id: 1, find: "find_value", create: nil>
after #=> #<Model id: 1, find: "find_value", create: nil>
# Otherwise:
before #=> nil
after #=> #<Model id: 2, find: "find_value", create: "create_value">
如果还希望它更新已存在的记录,请尝试:
Model.where(find: 'find_value').
first_or_create(create: 'create_value').
update(update: 'update_value')
# If one already exists:
before #=> #<Model id: 1, find: "find_value", create: nil, update: nil>
after #=> #<Model id: 1, find: "find_value", create: nil, update: "update_value">
# If it already matches, no UPDATE statement will be run:
before #=> #<Model id: 1, find: "find_value", create: nil, update: "update_value">
after #=> #<Model id: 1, find: "find_value", create: nil, update: "update_value">
# Otherwise:
before #=> nil
after #=> #<Model id: 2, find: "find_value", create: 'create_value', update: "update_value">
编辑2016-03-08:根据Doug的comment,如果您的验证在#create
和#update
来电之间失败,或者您希望最小化数据库呼叫时,您可以使用::first_or_initialize
来避免在第一次呼叫时保留记录。但是,必须确保您之后调用#save
或#update
以便保留记录(我不确定#update
是否适用于记录尚未坚持):
Model.validates :update, presence: true # The create call would fail this
Model.where(find: 'find_value').
first_or_initialize(create: 'create_value'). # doesn't call validations
update(update: 'update_value')
(注意。是一种名为#create_or_update
的方法,但不要被您在Google上找到的任何documentation所欺骗;这只是一种私有方法#save
。)
答案 2 :(得分:13)
您可能正在寻找first_or_create
或类似的东西:
http://guides.rubyonrails.org/v3.2.17/active_record_querying.html#first_or_create
答案 3 :(得分:4)
@student = Student.where(user_id: current_user.id).first
@student ||= Student.new(user_id: current_user.id)
@student.department_id = 1
@student.save
如果您在用户和学生之间建立关联,这会更漂亮。
的内容@student = current_user.student || current_user.build_student
@student.department_id = 1
@student.save
编辑:
您也可以使用http://guides.rubyonrails.org/active_record_querying.html#first_or_create作为sevenseacat的回答,但您仍需处理不同的情况,例如更新学生的部门ID。
更新:
您可以使用find_or_create_by
@student = Student.find_or_create_by(user_id: current_user.id) do |student|
student.department_id = 1
end
答案 4 :(得分:0)
不幸的是,我认为最简洁的方法是:
Student.where(user_id: id).first_or_create(age: 16).update_attribute(:age, 16)
答案 5 :(得分:0)
在Rails 5中
Student.
find_or_initialize_by(:user_id => current_user.id).
update(:department => 1)
(所有功劳均来自@Zorayr答案)。
答案 6 :(得分:-5)
find_or_create_by 而非 first_or_create 。
例如:
Client.find_or_create_by(first_name:'Andy')