RoR:如何从本地文件将图像播种到我的数据库

时间:2022-05-14 09:12:00

Codecademy shows one can seed images via a url like (in seeds.rb):

Codecademy显示可以通过类似(在seeds.rb中)的URL来播种图像:

t1 = Tag.create(title: "Beaches", image: "http://s3.amazonaws.com/codecademy-content/courses/learn-rails/img/beach01.jpg")
Destination.create(name: "Ipanema", description: "The beach of Ipanema is known for its elegant development and its social life.", image: "http://s3.amazonaws.com/codecademy-content/courses/learn-rails/img/beach02.jpg", tag_id: t1.id)

But what if I have a local file I would like to use instead? My file path is given in Ruby by

但是如果我想要使用本地文件呢?我的文件路径是在Ruby中给出的

File.join(Rails.root,'db','images','Event1.jpg')

I tried using

我试过用

image: File.open(File.join(Rails.root,'db','images','Event1.jpg'))

in place of

代替

image: "http://s3.amazonaws.com/codecademy-content/courses/learn-rails/img/beach02.jpg"

but it didn't work.

但它不起作用。

Currently I'm accessing the image in the view using

目前我正在使用视图访问图像

<%= image_tag t.image %>

How can I achieve this?

我怎样才能做到这一点?

1 个解决方案

#1


0  

You must first wrap your head around some concepts:

你必须首先围绕一些概念:

  1. You can't store the object returned by File.open or File.new. Those are just IO objects that reference a stream (more about it here). At least you need to get the image's contents with File.read so that you can store them and use them later.
  2. 您不能存储File.open或File.new返回的对象。这些只是引用流的IO对象(这里有更多关于它的信息)。至少你需要使用File.read获取图像的内容,以便您可以存储它们并在以后使用它们。
  3. Once you have the image's contents in a variable you may store it in your database. Beware that this is a big element, and you may need to scale your storage.
  4. 在变量中包含图像的内容后,您可以将其存储在数据库中。请注意,这是一个很大的元素,您可能需要扩展存储空间。
  5. Let's assume that you can retrieve this content from your db. How is image_tag supposed to know how to represent your stored data?
  6. 假设您可以从数据库中检索此内容。 image_tag如何知道如何表示您存储的数据?

Once you have that figured out, you might want to analyze some options on how to actually implement it:

一旦弄明白,您可能想要分析一些有关如何实际实现它的选项:

a. Store a binary blob or base 64 representation of your image. Before actually using it, write it in a local file and pass it as argument for image_tag. Cons: very inefficient. I put it as an option since it is what you're trying to do in the first place, but I don't think it is viable. Databases are not optimized to hold large amounts of data in a single column entry (take this with a grain of salt, since it depends on the DB engine and the way you are querying the data). Also, the reading from DB/writing to local file is quite slow, and you need to serve that image as fast as you can.

一个。存储图像的二进制blob或base 64表示。在实际使用它之前,将其写入本地文件并将其作为image_tag的参数传递。缺点:非常低效。我把它作为一个选项,因为它首先是你想要做的,但我不认为它是可行的。数据库未经过优化,无法在单个列条目中保存大量数据(因为它取决于数据库引擎和查询数据的方式)。此外,从DB /写入本地文件的读取速度非常慢,您需要尽可能快地提供该图像。

b. Store a reference to the file, and save the image locally (could be put in app/assets/images, for example). Then you can reference it with image_tag Rails.root.join('app', 'assets', 'images', t.filename). Cons: there's no straightforward way of knowing that your image is available.

湾存储对文件的引用,并在本地保存图像(例如,可以放在app / assets / images中)。然后你可以用image_tag Rails.root.join('app','assets','images',t.filename)引用它。缺点:没有直接的方式知道您的图像可用。

c. As in your CodeAcademy example, save the image in an external service and save a URL reference to it. There are several services that are specially designed for that, such as AWS S3. These are highly optimized for serving images and files in general, that's why it is better than serving the image all by yourself. But when you are big enough as, say, *, you might want to have your own storage service, since intensive usage might be better/cheaper than using an external service. So how to these external services do it? The may store it directly to disk. Then when you access that url a program serves that content just like another file, but putting the necessary headers so that your browser can interpret its contents (refer to concept 1. above). Edit: * does use external services: imgur.com/gravatar.com, use the "Inspect Element" tool of your browser and see for yourself :)

C。与CodeAcademy示例一样,将图像保存在外部服务中并保存对其的URL引用。有几种专门为此设计的服务,例如AWS S3。这些都是高度优化的,通常用于提供图像和文件,这就是为什么它比自己提供图像更好。但是当你足够大,比如*时,你可能想拥有自己的存储服务,因为密集使用可能比使用外部服务更好/更便宜。那么这些外部服务如何做呢?可以将其直接存储到磁盘。然后,当您访问该URL时,程序就像另一个文件一样提供该内容,但是放置必要的标题以便您的浏览器可以解释其内容(参见上面的概念1)。编辑:*确实使用外部服务:imgur.com/gravatar.com,使用浏览器的“Inspect Element”工具,亲眼看看:)

#1


0  

You must first wrap your head around some concepts:

你必须首先围绕一些概念:

  1. You can't store the object returned by File.open or File.new. Those are just IO objects that reference a stream (more about it here). At least you need to get the image's contents with File.read so that you can store them and use them later.
  2. 您不能存储File.open或File.new返回的对象。这些只是引用流的IO对象(这里有更多关于它的信息)。至少你需要使用File.read获取图像的内容,以便您可以存储它们并在以后使用它们。
  3. Once you have the image's contents in a variable you may store it in your database. Beware that this is a big element, and you may need to scale your storage.
  4. 在变量中包含图像的内容后,您可以将其存储在数据库中。请注意,这是一个很大的元素,您可能需要扩展存储空间。
  5. Let's assume that you can retrieve this content from your db. How is image_tag supposed to know how to represent your stored data?
  6. 假设您可以从数据库中检索此内容。 image_tag如何知道如何表示您存储的数据?

Once you have that figured out, you might want to analyze some options on how to actually implement it:

一旦弄明白,您可能想要分析一些有关如何实际实现它的选项:

a. Store a binary blob or base 64 representation of your image. Before actually using it, write it in a local file and pass it as argument for image_tag. Cons: very inefficient. I put it as an option since it is what you're trying to do in the first place, but I don't think it is viable. Databases are not optimized to hold large amounts of data in a single column entry (take this with a grain of salt, since it depends on the DB engine and the way you are querying the data). Also, the reading from DB/writing to local file is quite slow, and you need to serve that image as fast as you can.

一个。存储图像的二进制blob或base 64表示。在实际使用它之前,将其写入本地文件并将其作为image_tag的参数传递。缺点:非常低效。我把它作为一个选项,因为它首先是你想要做的,但我不认为它是可行的。数据库未经过优化,无法在单个列条目中保存大量数据(因为它取决于数据库引擎和查询数据的方式)。此外,从DB /写入本地文件的读取速度非常慢,您需要尽可能快地提供该图像。

b. Store a reference to the file, and save the image locally (could be put in app/assets/images, for example). Then you can reference it with image_tag Rails.root.join('app', 'assets', 'images', t.filename). Cons: there's no straightforward way of knowing that your image is available.

湾存储对文件的引用,并在本地保存图像(例如,可以放在app / assets / images中)。然后你可以用image_tag Rails.root.join('app','assets','images',t.filename)引用它。缺点:没有直接的方式知道您的图像可用。

c. As in your CodeAcademy example, save the image in an external service and save a URL reference to it. There are several services that are specially designed for that, such as AWS S3. These are highly optimized for serving images and files in general, that's why it is better than serving the image all by yourself. But when you are big enough as, say, *, you might want to have your own storage service, since intensive usage might be better/cheaper than using an external service. So how to these external services do it? The may store it directly to disk. Then when you access that url a program serves that content just like another file, but putting the necessary headers so that your browser can interpret its contents (refer to concept 1. above). Edit: * does use external services: imgur.com/gravatar.com, use the "Inspect Element" tool of your browser and see for yourself :)

C。与CodeAcademy示例一样,将图像保存在外部服务中并保存对其的URL引用。有几种专门为此设计的服务,例如AWS S3。这些都是高度优化的,通常用于提供图像和文件,这就是为什么它比自己提供图像更好。但是当你足够大,比如*时,你可能想拥有自己的存储服务,因为密集使用可能比使用外部服务更好/更便宜。那么这些外部服务如何做呢?可以将其直接存储到磁盘。然后,当您访问该URL时,程序就像另一个文件一样提供该内容,但是放置必要的标题以便您的浏览器可以解释其内容(参见上面的概念1)。编辑:*确实使用外部服务:imgur.com/gravatar.com,使用浏览器的“Inspect Element”工具,亲眼看看:)