0

I am trying to upload images without gem to a model called "Course Classifications", before I was using the gem "Paperclip". Rails Version is Rails 3.0.10

When I am trying to create a "Course Classification", I get the following error: undefined method `name 'for nil: NilClass

I suppose it must be something regarding the image that I am trying to upload, because when I do not load an image, the model is created normally.

according to my console the error is in the line of the method 'create' 'if @course_clasification.save'

What can be?

The 'puts' throw me the following:

"PARAMS: {\"name\"=>\"Prueba12312\", \"description\"=>\"\", \"status\"=>\"1\", \"picture\"=>#<ActionDispatch::Http::UploadedFile:0x0055ffb16c36d8 @original_filename=\"Selección_250.png\", @content_type=\"image/png\", @headers=\"Content-Disposition: form-data; name=\\\"course_clasification[picture]\\\"; filename=\\\"Selecci\\xC3\\xB3n_250.png\\\"\\r\\nContent-Type: image/png\\r\\n\", @tempfile=#<Tempfile:/tmp/RackMultipart20210722-21412-xnr47e>>}"
"NAME: Prueba12312"

My code is the following:

Controller:

     def create
        @course_clasification = CourseClasification.new(params[:course_clasification])
        p "PARAMS: #{params[:course_clasification]}"
        if params[:course_clasification].present?
          file = params[:course_clasification][:picture]
          File.open(Rails.root.join('public','uploads', file.original_filename), 'wb') do |f|
            f.write(file.read)
          end
        end
        respond_to do |format|
          if @course_clasification.save
            format.html { redirect_to(course_clasifications_path, :notice => 'Classification was created') }
            format.xml  { render :xml => @course_clasification, :status => :created, :location => @course_clasification }
          else
            format.html { render :action => "new" }
            format.xml  { render :xml => @course_clasification.errors, :status => :unprocessable_entity }
          end
        end
      end

  def upload
    uploaded_io = params.require(:course_clasification).permit(:picture)
    File.open(Rails.root.join('public','uploads',uploaded_io.original_filename), 'wb') do |file|
      file.write(uploaded_io.read)
    end
  end

Model:

class CourseClasification < ActiveRecord::Base
    has_many :courses
    has_many :enrollments

  validates :name, presence: true
=begin
    has_attached_file :avatar
    # Validate content type
    validates_attachment_content_type :avatar, content_type: /\Aimage/
    # Validate filename
    validates_attachment_file_name :avatar, matches: [/png\Z/, /jpe?g\Z/]
    # Explicitly do not validate
    do_not_validate_attachment_file_type :avatar
=end
    scope :actives, -> { where('status = 1') }
    scope :inactives, -> { where('status = 0') }


end

Form:

<%= form_for(@course_clasification, html: { style: "flex-direction: column; width: 50%;", :multipart => true }) do |f| %>
  <div class="actions">
    <%= link_to '<i class="fa fa-chevron-circle-left" aria-hidden="true"></i> Regresar'.html_safe, course_clasifications_path, class: "btn-button button--indigo" %>
    <%= f.submit(("&#xf0c7; " + t('action.save')).html_safe, :alt => "Guardar", :title => "Guardar", :class => "button__submit btn-button button--green", :style => "font-family: FontAwesome, verdana, sans-serif; float: right; margin-top: 0; margin-right: 7px;") %>
  </div>

  <% lang = current_user.localization.languaje %>
  <% if @course_clasification.errors.any? %>
    <div id="error_explanation">
      <h2><%= t('activerecord.errors.template.header', count: @course_clasification.errors.size, model: t('activerecord.models.course_clasification')) %>:</h2>
      <p>
        <%= t('activerecord.errors.template.body') %>
      </p>
      <ul>
      <% @course_clasification.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field field-full" style="margin-top: 40px;">
    <%= f.label t('str_name_areas_'+ lang) %><br />
    <%= f.text_field :name %>
  </div>

  <div class="field field-full">
    <%= f.label "Agregar imágen a player" %><br />
    <%= f.file_field :picture %>
    <%# if @course_clasification.avatar? %>
      <%# image_tag @course_clasification.avatar.url(:thumb) %>
    <%# end %>
  </div>

<% end %>

Schema:

class CreateCourseClasification < ActiveRecord::Migration
  def self.up
    create_table :course_clasifications do |t|
      t.string :name
      t.text :description
      t.boolean :status
      t.string :picture

      t.timestamps
    end
  end

end
Nicolás
  • 55
  • 7

1 Answers1

0

One problem that I'm seeing is that you're not using Strong Parameters. That means that

@course_clasification = CourseClasification.new(params[:course_clasification])

Will basically try to create an empty object since non of the params is whitelisted (whatever is not whitelisted is basically omitted by Rails), so the ActiveRecord object is invalid and the save fails. Change it to something like

def course_classification_params
    # make sure to list all the save params!
    params.permit(:name, :description, :status, ...)
end

@course_clasification = CourseClasification.new(course_classification_params[:course_clasification])

Joel Blum
  • 7,750
  • 10
  • 41
  • 60
  • you're right, but this is a slightly old rails project and is still in production. Unfortunately, your advice does not solve the problem I have :( Thanks for u advice – Nicolás Jul 22 '21 at 23:58
  • Ah. You better write the Rails version in the question then, people will usually assume you're not on a super old one. – Joel Blum Jul 23 '21 at 00:00
  • yeah, I forgot that. I've corrected Thanks! – Nicolás Jul 23 '21 at 00:02