Я много боролся, и в конечном итоге метод, который позволил мне заставить его работать с Rails 4, был:
на вашем старом сервере
sudo su - postgres
pg_dump -c --inserts old_db_name > dump.sql
Мне пришлось использовать postgres linux для создания дампа. также мне пришлось использовать -c для создания базы данных на новом сервере. --inserts сообщает ему использовать синтаксис INSERT (), который в противном случае не работал бы для меня: (
, затем на новом сервере simpy:
sudo su - postgres
psql new_database_name < dump.sql
, чтобы передать Файл dump.sql между сервером Я просто использовал «cat» для печати содержимого, а не «nano», чтобы воссоздать его, копируя содержимое.
Кроме того, ROLE i использовал в обеих базе данных, я должен был найти - заменить все имя владельца в дампе.
Возможно, вы ищете first_or_create
или что-то похожее:
http://guides.rubyonrails.org/v3.2.17/active_record_querying.html#first_or_create
В рельсах 4
Student.
find_or_initialize_by(:user_id => current_user.id).
update_attributes!(:department => 1)
::first_or_create
(доступно начиная с версии 3.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: Согласно Дагу комментарий , если ваши проверки не выполняются между вызовами #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')
(NB. Существует метод , называемый #create_or_update
, но не обманывайте себя никакими документами , которые вы можете найти в Google; это просто частный метод, используемый #save
.)
В Rails 5
Student.
find_or_initialize_by(:user_id => current_user.id).
update(:department => 1)
(все отзывы взяты из ответа @Zorayr).
@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, но вам все еще приходится иметь дело с различными сценариями, такими как обновление идентификатора студенческого отделения.
ОБНОВЛЕНИЕ:
Вы можете использовать find_or_create_by
@student = Student.find_or_create_by(user_id: current_user.id) do |student|
student.department_id = 1
end
К сожалению, я думаю, что самый чистый способ сделать это:
Student.where(user_id: id).first_or_create(age: 16).update_attribute(:age, 16)
Это find_or_create_by , а не first_or_create .
Пример: Client.find_or_create_by (имя: «Энди»)