0

我有以下帮助方法,用于将一些记录上传到 Dropbox。对于三个模型(日志、飞机和进近)中的每一个,我都在做完全相同的事情。我想让这个更干燥,并且只有一次代码,但我不明白如何以抽象的方式引用模型。

有什么建议吗?

#------------------------------------------------------------
# Upload entries to Dropbox
#------------------------------------------------------------
def upload_items(items, folder, client)

  # Go through each item and upload it to Dropbox
  items.each do |item|

    if folder == 'logbook'
      # Get the file from the database to upload
      @logbook = current_user.logbooks.find_by_sync_id(item)
      # Upload it
      uploaded_file = client.put_file("/logbook/#{item}.json",@logbook.to_json, overwrite = true)
      # Reset the updated_flag in the database
      @logbook.update_attributes(updated_flag: 0)

    elsif folder == 'aircraft'
      # Get the file from the database to upload
      @aircraft = current_user.aircrafts.find_by_sync_id(item)
      # Upload it
      uploaded_file = client.put_file("/aircraft/#{item}.json",@aircraft.to_json, overwrite = true)
      # Reset the updated_flag in the database
      @aircraft.update_attributes(updated_flag: 0)

    elsif folder == 'approaches'
      # Get the file from the database to upload
      @approach = current_user.approaches.find_by_sync_id(item)
      # Upload it
      uploaded_file = client.put_file("/approaches/#{item}.json",@approach.to_json, overwrite = true)
      # Reset the updated_flag in the database
      @approach.update_attributes(updated_flag: 0)

    end
  end
end

Ruby 1.9.3,Rails 3.2.8

4

3 回答 3

1

这将完成这项工作。

下面的关键部分是current_user.public_send(folder.to_sym)获取文件夹名称并将其转换为要发送给 current_user 的消息。

#------------------------------------------------------------
# Upload entries to Dropbox
#------------------------------------------------------------
def upload_items(items, folder, client)

  # Go through each item and upload it to Dropbox
  items.each do |item|
    # Get the file from the database to upload
    resource = current_user.public_send(folder.pluralize.to_sym).find_by_sync_id(item)
    # Upload it
    uploaded_file = client.put_file("/#{folder}/#{item}.json",resource.to_json, overwrite = true)
    # Reset the updated_flag in the database
    resource.update_attributes(updated_flag: 0)
  end
end
于 2013-01-09T17:32:31.737 回答
1

我会这样写:

class DropboxUploader
  attr_reader :folder, :client

  def initializer(folder, client)
    @folder = folder.to_sym
    @client = client
  end

  def upload(items)
    items.each { |item| update item }
  end

  def resource_name
    folder.to_s.pluralize.to_sym
  end

  def file_path
    "/#{folder}/#{item}.json"
  end

  private
  def find_resource_for(item)
    current_user.public_send(resource_name).find_by_sync_id(item)
  end

  def update(item)
    resource = find_resource_for item
    client.put_file(file_path, @aircraft.to_json, true)
    resource.update_attributes(updated_flag: 0)
  end
end

不仅 DRY,而且更客观(并且更容易测试)。

编辑: 用法如下:

uploader = DropboxUploader.new(:aircraft, @client)
uploader.upload(@items)
于 2013-01-09T17:38:07.327 回答
0

这应该是方向:

你的控制器:

#------------------------------------------------------------
# Upload entries to Dropbox
#------------------------------------------------------------
def upload_items(items, folder, client)

  # Go through each item and upload it to Dropbox
  items.each do |item|
   upload_to_dropbox(items, folder, client)
  end
end

应用控制器:

def upload_to_dropbox(item, folder, client)
  # Get the file from the database to upload
  @model = current_user.send(folder).find_by_sync_id(item)
  # Upload it
  uploaded_file = client.put_file("/aircraft/#{item}.json",@model.to_json, overwrite = true)
  # Reset the updated_flag in the database
  @model.update_attributes(updated_flag: 0)
end
于 2013-01-09T17:34:13.153 回答