我尝试使用.rake
文件保存记录。但是在尝试保存更改时出现错误。
返回Error.message
SQLite3::ConstraintException: UNIQUE constraint failed: versions.id: INSERT INTO "versions" ("app_id", "created_at", "icon_url", "id", "plist_url", "updated_at", "version_number") VALUES (?, ?, ?, ?, ?, ?, ?)
inbox.rake文件
namespace :inbox do
desc 'Check inbox for new app builds'
task process_inbox: :environment do
# initialize s3 client
s3 = AWS::S3.new
bucket = s3.buckets['my-bucket']
s3_host = 'https://...s3.amazonaws.com/'
exclude_inbox = bucket.objects.select do |s3_object|
s3_object.key.exclude? '_inbox'
end
#find plist within the inbox
plist_objects = exclude_inbox.select do |s3_object|
s3_object.key.include? 'plist'
end
for plist_object in plist_objects
plist = CFPropertyList::List.new(:data => plist_object.read)
data = CFPropertyList.native_types(plist.value)
name = data['items'][0]['metadata']['title']
bundle_version = data['items'][0]['metadata']['bundle-version']
plist_copy = plist_object.copy_to("#{name}/#{bundle_version}/#{name}.plist")
kind = data['items'][0]['metadata']['kind']
plist = CFPropertyList::List.new(:data => plist_copy.read)
data = CFPropertyList.native_types(plist.value)
icon_url = data['items'][0]['assets'][1]['url']
full_url = plist_copy.url_for(:read)
icon = bucket.objects[icon_url.gsub(s3_host, '')]
#find app or create a new app based on its name and kind
app = App.find_or_initialize_by(name: name, app_type: kind)
#app.save unless app.id
#find version or create new version base on app_id and bundle_version
version = Version.find_or_initialize_by(app_id: app.id, id: bundle_version)
version.plist_url = full_url.scheme + '://' + full_url.host + full_url.path
version.icon_url = icon.copy_to("#{name}/#{bundle_version}/#{icon_url.split('/').last.gsub('~','_')}").url_for(:read).to_s
version.version_number = bundle_version
version.app = app
#update app version number
app.version_number = version.version_number
#save changes
begin
app.save
version.save
puts app.attributes , version.attributes
rescue => error
puts error.message
end
end
end
end
答案 0 :(得分:1)
这一行是问题
Version.find_or_initialize_by(app_id: app.id, id: bundle_version)
我猜这里的id是主键。由于您在两个值上执行find_or_initialize
,因此当数据库中存在具有给定bundle_version但版本不同的版本时,您将获得新版本
你可能应该这样做,
version = Version.find_or_initialize_by(id: bundle_version)
version.app_id = app.id
答案 1 :(得分:1)
这是有问题的一行:
version = Version.find_or_initialize_by(app_id: app.id, id: bundle_version)
这更详细但可能更符合您的要求:
version = Version.find_by(id: bundle_version, app_id: app.id) || Version.new(app_id: app.id)