0

I've created a form so the user can add a new picture to the website catalog, but for some reasons it doesn't work. Once the form is filled out, I click on the 'Submit' button but nothing happens, I just stay on the same page (and I don't have any error message...). I don't think the error comes from my Controller since nothing happens when I add the raise keyword in my Controller's 'create' method.

I'm sure this is an amateur mistake... but I can't see what it is. Thanks for your help!

picture.rb / Picture model:

class Picture < ApplicationRecord
  validates :name, presence: true
  has_many_attached :photo
end

new.html.erb / Here is my form :

<%= form_for(@picture) do |f| %>
  <div class="form-group">
    <%= f.label :name, "Please indicate the name" %>
    <%= f.text_field :name, class:"form-control", placeholder:"(mandatory field)" %>
  </div>
  <div class="form-group">
    <%= f.label :description, "Add a description" %>
    <%= f.text_area :description, class:"form-control" %>
  </div>
  <div class="form-group">
    <div class="row">
      <div class="col">
        <%= f.label :category, "Add a category" %>
        <%= f.text_field :category, class:"form-control" %>
      </div>
      <div class="col">
        <%= f.label :price, "Indicate the price (when applicable)" %>
        <%= f.number_field :price, class:"form-control", placeholder:"0,00$ CAD" %>
      </div>
    </div>
  </div>
  <div class="form-group">
    <div class="row">
      <div class="col">
        <p>Where do you want to add this item?</p>
          <div>
            <%= f.check_box :is_home_item %>
            <%= f.label :is_home_item, "Homepage" %>
          </div>
          <div>
            <%= f.check_box :is_portfolio_item %>
            <%= f.label :is_portfolio_item, "Work" %>
          </div>
          <div>
            <%= f.check_box :is_sketchbook_item %>
            <%= f.label :is_sketchbook_item, "Sketchbook" %>
          </div>
        <div>
          <%= f.check_box :is_shopping_item %>
          <%= f.label :is_shopping_item, "Shopping" %>
        </div>
      </div>
      <div class="col">
        <div class="form-group">
          <%= f.label :photo, "Select your picture" %>
          <%= f.file_field :photo, class:"form-control-file" %>
        </div>
      </div>
    </div>
  </div>
  <div class="form-group">
    <%= f.submit class:"btn btn-lg btn-primary" %>
  </div>
<% end %>

pictures_controller.rb /

class PicturesController < ApplicationController
  def new
    @picture = Picture.new
  end

  def create
    @picture = Picture.new(picture_params)
    if @picture.save
      redirect_to root_path(@picture), notice: "Picture was successfully created"
    else
      render :new
    end
  end

  private

  def picture_params
    params.require(:picture).permit(:name, :description, :category, :price, :is_home_item, :is_portfolio_item, :is_sketchbook_item, :is_shopping_item, :photo)
  end
end

And here is the text I got on my local server console

Here is the HTML output of my form :

<form>
<input type="hidden" name="authenticity_token" value="7MxWbzbltjXcAx2dvgRwIu07WMpyjPQji6LI6ELifMZODLJyMBucNApnPRk8vsjshSEjyMMenDUfvDw6pN+/4Q==">
  <div class="form-group">
    <label for="picture_name">Indicate the name</label>
    <input class="form-control" placeholder="(mandatory field)" type="text" name="picture[name]" id="picture_name">
  </div>
  <div class="form-group">
    <label for="picture_description">Add a description</label>
    <textarea class="form-control" name="picture[description]" id="picture_description"></textarea>
  </div>
  <div class="form-group">
    <div class="row">
      <div class="col">
        <label for="picture_category">Add a category</label>
        <input class="form-control" type="text" name="picture[category]" id="picture_category">
      </div>
      <div class="col">
        <label for="picture_price">Indicate the price (when applicable)</label>
        <input class="form-control" placeholder="0,00$ CAD" type="number" name="picture[price]" id="picture_price">
      </div>
    </div>
  </div>
  <div class="form-group">
    <div class="row">
      <div class="col">
        <p>Where do you want to add your picture?</p>
          <div>
            <input name="picture[is_home_item]" type="hidden" value="0"><input type="checkbox" value="1" name="picture[is_home_item]" id="picture_is_home_item">
            <label for="picture_is_home_item">Homepage</label>
          </div>
          <div>
            <input name="picture[is_portfolio_item]" type="hidden" value="0"><input type="checkbox" value="1" name="picture[is_portfolio_item]" id="picture_is_portfolio_item">
            <label for="picture_is_portfolio_item">Work</label>
          </div>
          <div>
            <input name="picture[is_sketchbook_item]" type="hidden" value="0"><input type="checkbox" value="1" name="picture[is_sketchbook_item]" id="picture_is_sketchbook_item">
            <label for="picture_is_sketchbook_item">Sketchbook</label>
          </div>
        <div>
          <input name="picture[is_shopping_item]" type="hidden" value="0"><input type="checkbox" value="1" name="picture[is_shopping_item]" id="picture_is_shopping_item">
          <label for="picture_is_shopping_item">Shopping</label>
        </div>
      </div>
      <div class="col">
        <div class="form-group">
          <label for="picture_photo">Select your picture</label>
          <input class="form-control-file" type="file" name="picture[photo]" id="picture_photo">
        </div>
      </div>
    </div>
  </div>
  <div class="form-group">
    <input type="submit" name="commit" value="Create Picture" class="btn btn-lg btn-primary" data-disable-with="Create Picture">
  </div>

My routes :

Rails.application.routes.draw do
  devise_for :users
  
  # Pages routes
  root to: 'pages#home'
  get 'about', to: 'pages#about'
  get 'portfolio', to: 'pages#portfolio'
  get 'sketchbook', to: 'pages#sketchbook'
  get 'shopping', to: 'pages#shopping'
  
  # Pictures routes
  resources :pictures

end

And these are my routes in the Terminal

6
  • Change <%= form_for(@picture) do |f| %> to <%= form_for(@picture, local: true) do |f| %>. Commented Feb 19, 2021 at 17:44
  • Thanks @sam but unfortunately it doesn't work :/ Commented Feb 20, 2021 at 0:55
  • Hmm... you might want to change form_for to form_with(model: @picture. If that doesn't work, what does it say in console when you click submit? Commented Feb 20, 2021 at 2:17
  • It still doesn't work :/ I added at the end of my original message a screenshot of the text I got on my local server console Commented Feb 20, 2021 at 18:27
  • Okay. So it's making a GET request to pictures#new. You need it to make a PUT request to pictures#create. My guess now is that one of two things is going on. You either have your routes configured wrong (they should be resources :pictures) or for some reason your form_with is not defaulting to a post method with the right action. Can you add the html output of your form? You can strip out the authenticity token part, just the line that starts <form. And also your routes line(s) for pictures. Commented Feb 20, 2021 at 19:17

2 Answers 2

0

Not quite sure why this is happening, but form_for is deprecated, so you should replace it with form_with.

You can use a model, such as your @picture with form_with as described in the docs.

<%= form_with(model: @picture) do |form| %>
  # fields
<% end %>

This should create a form DOM object that looks like this:

<form action="/pictures" method="post" accept-charset="UTF-8" >
  <input name="authenticity_token" type="hidden" value="..." />
  ...
</form>

If for some reason it doesn't, you can always pass a method: :post in the form_with (ie. <%= form_with(model: @picture, method: :post) do |form| %>).

Sign up to request clarification or add additional context in comments.

3 Comments

Again thanks for your help Sam! Actually I already tried that but it doesn't work. Do you think it could be a database issue (instead of a coding issue) ? Something to do with ActiveRecords or Active Storage maybe ? I'm wondering if I set up my database correctly...
I don't think so. Right now your issue is the GET request. You need to get that part solved. You could try removing the photo and just see if you can save the name, though. Also in the console run Picture.create!(name: 'Test Picture') to make sure there's no DB issue.
I tried that in the console and it worked. So you were right, the issue was somewhere else. As mentioned by Ayushi in her comment, the problem was coming from my Picture model. I updated it and my picture_params method and it's now working. Thanks for all your help!
0

Currently, you have got has_many_attached with a singular photo. That does not seem to be the right syntax. Have you tried changing to has_many_attached :photos and modifying the picture_params to have photos passed as an array photos: []?

Or if you wanted to attach one photo, then you should try changing to has_one_attached :photo in the Picture model.

1 Comment

It worked! I updated the Picture model with has_many_attached :photos and also modified the picture_params to have photos passed as an array photos: [] and it seems to be working. Thanks so much for your help Ayushi :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.