[RUBY] Image registration? Of course I can't (can) ~ part2 ~

Premise

--Use ruby on rails 6.0.0. --User functions are assumed to be introduced by devise. --All view files are in haml format. ――By the way, I'm using MacBook Air (Retina, 13-inch, 2020).

Introduction

The introduction and procedure are described in part1 , so I will continue the implementation immediately. If you are interested, please read it.

The second part of the procedure, part2, is "Implementing image posting by associating the image table".

I just register the image in a separate table, but it took about 30,000 years to implement it, so I would like to leave the correct procedure for posterity.

Let's get started

Let's do our best today.

$ rails g model image $ rails db:migrate

First, create an image model and migrate it. As with the last time, the description of the migration file is omitted.

Next, I will explain the model structure.

app/models/product.rb


class Product < ApplicationRecord
  belongs_to :user
  has_many :images
end

app/models/image.rb


class Image < ApplicationRecord
  belongs_to :product
end

As you can see above, there is a one-to-many relationship where you can have multiple image models for one product model. (Validation is omitted for clarity) In the image table, one record corresponds to one image, and product_id is associated with each.

Now that you have a rough idea of the structure, we will prepare to upload the image in the local environment.

Gemfile


~abridgement~
gem 'carrierwave'
gem 'mini_magick'

First is the introduction of gems. This time I would like to use carrierwave's uploader to upload images.

$ bundle install $ rails g uploader image

Don't forget to do a bandle install and then generate the uploader file. In order to use these properly, let's add a description to the generated uploader file and the previous model.

app/models/image.rb


class Image < ApplicationRecord
  belongs_to :product
  mount_uploader :src, ImageUploader
end

By writing like this, it is possible to use ImageUploader in the src column of the image model.

app/uploaders/image_uploader.rb


include CarrierWave::MiniMagick
process resize_to_fit: [50, 50]

This is the Mini Magick setting. It's a convenient gem that allows you to adjust the size of the uploaded image. Rather than adding a new line above, you will find this description in the comment out and uncomment it. (You can freely adjust the contents of the resize)

Now that you can upload the image, let's create a form to actually post the image.

app/models/product.rb


class Product < ApplicationRecord
  belongs_to :user
  has_many :images, dependent: :destroy
  accepts_nested_attributes_for :images, allow_destroy: true
end

haml:app/views/products/_form.html.haml


= form_with model: @product, local: true do |f|
  = f.text_field :name, placeholder: 'name'
  = f.fields_for :images do |i|
    = i.file_field :src
  = f.submit 'SEND'

Something like fields_for came out. This is a form helper that can save data to multiple tables associated with one table at the same time. To use it, first add the description accepts_nested_attributes_for to the parent model. Let's have a child model associated with the factor. The allow_destroy part that follows is a convenient function that if you set it to true, if the parent record is deleted, the related child record will be deleted at the same time.

app/controllers/products_controller.rb


#~abridgement~
  def new
    @product = Product.new
    @product.images.new
  end
#~abridgement~
  def product_params
    params.require(:product).permit(:name, images_attributes: [:src]).merge(user_id: current_user.id)
  end 
#~abridgement~
end

We will make some modifications to the controller according to the data to be handled. First, in the new action part, we have added a description that creates a new image instance related to the product. Note that without this, the image will not be saved correctly in image. And it's a strong parameter. This is a little special description. _attributes: [:] means to specify the columns of the associated model. I think it's okay if you think of it as a set when you use the form helper fields_for.

This completes the image posting function. However, at this rate, only one image can be selected, so I would like to upgrade it next time.

Finally

This time, I created an image model, actually sent the image in a form, and implemented it up to saving it in the database.

I thought it would be difficult to understand with just the letters, so I wanted to add reference images and gifs. I'm a little busy right now, so I'll do it if I can afford it. (Perhaps)

In part3, we will finally introduce jQuery. Let's make a form that allows you to post multiple images by playing around with the display! It's like that. I will do my best.

See you in the next part. Thank you very much.

I want to implement the product information editing function ~ part3 ~

Recommended Posts

Image registration? Of course I can't (can) ~ part2 ~
I made a Docker image of SDAPS for Japanese
I am keenly aware of the convenience of graphql-code-generator, part 2
I can't get out of the Rails dbconsole screen