rootstrap / active-storage-base64

Base64 support for ActiveStorage
https://rootstrap.com
MIT License
160 stars 16 forks source link

MISSING IO #51

Closed guyeatspants closed 4 years ago

guyeatspants commented 4 years ago

Hello all! Thank you for coming to check out this thread, I looked at the other threads and haven't been able to find a solution.

I have an canvas, on form submit it fills a hidden field with base64 data 'data:image/png;base64,[**base64 data**]'

In my article model i have

include ActiveStorageSupport::SupportForBase64

  has_one_base64_attached :article_image, dependent: :destroy
    validates :article_image, {
    presence: true
  }

In my create action in my controller I have..

` def create @article = current_user.articles.new(article_params)

@article.article_image.attach(data: params[:article_image], filename: "1_#{Time.current.to_i}")
respond_to do |format|
  if @article.save
    format.html { redirect_to @article, notice: 'Article was successfully created.' }
    format.json { render :show, status: :created, location: @article }
  else
    format.html { render :new }
    format.json { render json: @article.errors, status: :unprocessable_entity }
  end
end

end`

I've tried all code variations on rootstraps git and nothing works.. I get the same constant error.

ArgumentError in ArticlesController#create missing keyword: io

  @article.article_image.attach(data: params[:article_image], filename: "1_#{Time.current.to_i}")
    respond_to do |format|
      _if @article.save_
        format.html { redirect_to @article, notice: 'Article was successfully created.' }
        format.json { render :show, status: :created, location: @article }
      else

If anyone can help I'd greatly greatly appreciate it! The form populates, I can see it in my terminal but I get this IO error even in the terminal when the article is trying to save.

THANK YOU GUYS!!! Alex

santib commented 4 years ago

Hi @diagraphic , to help us troubleshoot the issue would you mind telling us:

  1. ruby version
  2. rails version
  3. active_storage_base64 version ?

Apart from that, seems that this issue is similar to the ones already solved https://github.com/rootstrap/active-storage-base64/issues?q=is%3Aissue+is%3Aclosed .

What is the line that is raising the exception? Is it:

  1. @article = current_user.articles.new(article_params)
  2. @article.article_image.attach(data: params[:article_image], filename: "1_#{Time.current.to_i}") ?

If 1. would you mind providing the code for article_params ? if 2. would you mind providing the format of params[:article_image] (with format I mean if it's a string or a hash and the format of the base64 string)

guyeatspants commented 4 years ago

Hello Santiago! I can, absolutely.

Ruby 2.6.3 Rails 6.0.3 ActiveStorage base46 v1.1

Params params.require(:article).permit(:title, :body, :user_id, article_image: :data ) or like the documentation says to not include the blank: :data if you're not using strong parameters.

Like 2 i believe is causing the exception because the missing IO error.. if i don't include filename I'll get filename missing in with the IO error.

on form submit i can see in my terminal and in chrome views that my hidden input is getting populated with 'data:image/png;base64,[base64 data]'

My JS is simple and working fine

base644 = function(el) {
  var imgData = canvas.toDataURL('image/png');
  alert(imgData);
   $('#damn').val(imgData);

};
santib commented 4 years ago

Great @diagraphic thanks for the details. I just tried in the console with the same versions doing:

article = Article.last
article.article_image.attach(data: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAADElEQVQImWNgoBMAAABpAAFEI8ARAAAAAElFTkSuQmCC", filename: "1_#{Time.current.to_i}")

and it worked fine. Would you mind trying that same thing in your dev console?

My take is that @article = current_user.articles.new(article_params) is the line failing to you and not the second one (that does the attach). Why? Because if you are manually attaching the image in a separate line of code, why are your permitting article_image: :data in the permitted params? you should do that if you want to send a JSON like: { article: { ..., article_image: { data: 'data:image/png;base64,[base64 data]' } } } but I think you are sending: { article: { ... }, article_image: { data: 'data:image/png;base64,[base64 data]' } }

and when it tried to automatically create the article_image as a nested resource it fails.

Possible solutions:

  1. Change your JSON to send the article_image inside the article hash
  2. Remove article_image: :data from your strong parameters
guyeatspants commented 4 years ago

I'm confused regarding the json.  I didn't setup any JSON for this just javascript to populate the hidden input, do you mind explaining what you mean so i can setup the json properly.  Thank you On Thursday, May 14, 2020, 02:17:33 PM EDT, Santiago Bartesaghi notifications@github.com wrote:

Great @diagraphic thanks for the details. I just tried in the console with the same versions doing: article = Article.last article.articleimage.attach(data: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAADElEQVQImWNgoBMAAABpAAFEI8ARAAAAAElFTkSuQmCC", filename: "1#{Time.current.to_i}") and it worked fine. Would you mind trying that same thing in your dev console?

My take is that @article = current_user.articles.new(article_params) is the line failing to you and not the second one (that does the attach). Why? Because 1. if you are manually attaching the image in a separate line of code, why are your permitting article_image: :data in the permitted params? you should do that if you want to send a JSON like: { article: { ..., article_image: { data: 'data:image/png;base64,[base64 data]' } } } but I think you are sending: { article: { ... }, article_image: { data: 'data:image/png;base64,[base64 data]' } }

and when it tried to automatically create the article_image as a nested resource it fails.

Possible solutions:

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe.

santib commented 4 years ago

@diagraphic sorry for the confusion, I shouldn't have talk about JSON, you can ignore that part.

I'm was referring to the post body (params in rails), I think you are sending something like { article: { ... }, article_image: { data: 'data:image/png;base64,[base64 data]' } } which is making the creation of the article fail because in your strong parameters article_params you are permitting article_image: :data. If you are going to permit that, then you don't need the explicit .attach call and you need to send the request body like this: { article: { ..., article_image: { data: 'data:image/png;base64,[base64 data]' } } } notice that the article_image is INSIDE the article.

Otherwise if you want to keep the explicit .attach call you need to remove article_image: :data from your strong params article_params and that's it.

guyeatspants commented 4 years ago
# POST /articles
  # POST /articles.json
  def create
    @article = current_user.articles.new(article_params)

    respond_to do |format|
      if @article.save
        format.html { redirect_to @article, notice: 'Article was successfully created.' }
        format.json { render :show, status: :created, location: @article }
      else
        format.html { render :new }
        format.json { render json: @article.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /articles/1
  # PATCH/PUT /articles/1.json
  def update
    respond_to do |format|
      if @article.update(article_params)
        format.html { redirect_to @article, notice: 'Article was successfully updated.' }
        format.json { render :show, status: :ok, location: @article }
      else
        format.html { render :edit }
        format.json { render json: @article.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /articles/1
  # DELETE /articles/1.json
  def destroy
    @article.destroy
    respond_to do |format|
      format.html { redirect_to articles_url, notice: 'Article was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_article
      @article = Article.friendly.find(params[:id])
    end

    # Only allow a list of trusted parameters through.
    def article_params
      params.require(:article).permit(:title, :body, :user_id, article_image: :data )
    end
end

Fail

Onclick this is my rails hidden input output on chrome, it changes right as i click

<input class="hidden" type="hidden" value="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAfQAAAI2CAYAAACmHnqoAAAgAElEQVR4Xuy9Wc8l2XUltmKOuPM35lCZNbM4F8miSIkaLLRpyu2WG7YBCwYMP/gvGH7zm1/8I/zgBcPQqKUBs7/M2IdUa1Q7+due75nhK3/G8Fea+Z36vnGf17snv9SHmm388Lt9Pr6kpokgGECnD2uQuLpGAZVOAAxGnnrgkYNgEb06rYhltocdV4kAa5/yNSzCtfSW0GN1YJudzI+R9ghYunKiCUJmkvJOSGDgCb0gTMXuicaAY2ARkAjoBE4bgQ0oR83dPpCjYBGQCOgEdAIDBwENKEPnLnQPdEIaAQ0AhoBjcBxI6AJ/bih0xdqBDQCGgGNgEZg4CCgCX3gzIXuiUZAI6AR0AhoBI4bAU3oxw2dvlAjoBHQCGgENAIDBwFN6ANnLnRPNAIaAY2ARkAjcNwIaEI/buj0hRoBjYBGQCOgERg4CPw/SYLjuA70mmoAAAAASUVORK5CYII=" name="article[article_image]" id="article_article_image">

Looks like the correct formatting?

guyeatspants commented 4 years ago

So.. now the post saved and i get this in teriminal.. we might be getting somewhere here!!!

rocessing by ArticlesController#create as HTML Parameters: {"authenticity_token"=>"cj71jShsncHMU+p8vbRVlEDxZb9BLzfedNbbtUif5oIqw6J/pZn2/Xdd9dT5BRRH5gHi2LOAU7uq1IRCGodw3A==", "article"=>{"article_image"=>"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAfQAAAI2CAYAAACmHnqoAAAgAElEQVR4Xuy9Wc8l2XUltmKOuPM35lCZNbM4F8miSIkaLLRpyu2WG7YBCwYMP/gvGH7zm1/8I/zgB7sbhtGAux9sSla34ZYtq7s1ciqyiqw5KyuHb7xjzBHG2hE7vnMj75dZTUkGBNR+iXtjjhMnzjp7Wtuq67rGZ/JZC3zWAp+1wGct8FkLfNYCf6dbwPoM0P9Ov7/Pbv6zFvisBT5rgc9a4LMWkBawkmTzmYb+WWf4rAU+a4HPWuCzFvisBf6Ot4D1X/83/20db04QDY6gS32m69b/TT3z084/HaeYL4Mn7sm8No+f+TVS93jnLek5dKP5/7pn5b794/rH63YuKcnFHOHetLuH/n8+R1A83trnb6oNP815LH8PdXbR7ar/P82SB5nHyiywPZ953v66oTeS663zVTNz9PcwqPPuHjaWh+EJsD5qVpm/uR+3m0s9kOfjuXVpPn9/m15b99/VVuY2fQau0+ub15X7bJ9r13X

santib commented 4 years ago

@diagraphic the article got saved? does it have the image attached then?

That message seems to be just a log message, I don't see any error there

guyeatspants commented 4 years ago

Well, <%= image_tag(@article.article_image) %> calling the image on the show page resolves in this error: Can't resolve image into URL: to_model delegated to attachment, but attachment is nil Argument error,

I guess it may have saved? I don't think so im not too sure.

Any ideas?

guyeatspants commented 4 years ago

`ActionView::Template::Error (Can't resolve image into URL: to_model delegated to attachment, but attachment is nil): 12:

13: 14:
15: <%= image_tag(@article.article_image) %> 16:
17: 18:

app/views/articles/show.html.erb:15`

It did not attach thats from in the terminal.

guyeatspants commented 4 years ago
Started PATCH "/articles/wewew" for ::1 at 2020-05-14 15:06:15 -0400
Processing by ArticlesController#update as HTML
  Parameters: **{"authenticity_token"=>"Ne0JKF7cTFQrZWE7Boce02RWX9QGk5vHNZwx6Io3ySBtEF7a0yknaJBrfpNCNl8AwqbYs/Q8/6Lrnm4f2C9ffg==", "article"=>{"article_image"=>"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwAAACoCAYAAABaK9MPAAAgAElEQVR4XqS
7O8G2qtXS+uMa0ZgahoHnGKTonMf17wHoqiMYD7FFAAu8J2VwwQI+GYb4YarDa2MWlNEa9M74jvg4Kuinc6733u3ICg6CqAJUCu37sWWSbr5x2rgQ9sa+ci5WUhku10Rml8q4nNMsfO+oza71Q4kXJHNidqZ9KdfrEIAED/meiQErQjBOFYpSNP7z/x9E1BaDEnJ8bgAAAABJRU5ErkJggg==", "title"=>"wewew", "body"=>"<div>ewew</div>", "channel_id"=>"9"}, "commit"=>"Update Article", "id"=>"wewew"}**
  Article Load (0.3ms)  SELECT "articles".* FROM "articles" WHERE "articles"."slug" = $1 LIMIT $2  [["slug", "wewew"], ["LIMIT", 1]]
  ↳ app/controllers/articles_controller.rb:71:in `set_article'
Unpermitted parameters: :article_image, :channel_id
   (0.2ms)  BEGIN
  ↳ app/controllers/articles_controller.rb:48:in `block in update'
  User Load (0.2ms)  SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2  [["id", 3], ["LIMIT", 1]]
  ↳ app/controllers/articles_controller.rb:48:in `block in update'
   (0.2ms)  COMMIT
  ↳ app/controllers/articles_controller.rb:48:in `block in update'
Redirected to http://localhost:3000/articles/wewew
Completed 302 Found in 8ms (ActiveRecord: 0.9ms | Allocations: 4393)
` Rendering articles/show.html.erb within layouts/application
  User Load (0.3ms)  SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2  [["id", 3], ["LIMIT", 1]]
  ↳ app/views/articles/show.html.erb:11
  ActiveStorage::Attachment Load (0.3ms)  SELECT "active_storage_attachments".* FROM "active_storage_attachments" WHERE "active_storage_attachments"."record_id" = $1 AND "active_storage_attachments"."record_type" = $2 AND "active_storage_attachments"."name" = $3 LIMIT $4  [["record_id", 30], ["record_type", "Article"], ["name", "article_image"], ["LIMIT", 1]]
  ↳ app/views/articles/show.html.erb:15
  Rendered articles/show.html.erb within layouts/application (Duration: 6.6ms | Allocations: 3524)
Completed 500 Internal Server Error in 13ms (ActiveRecord: 1.1ms | Allocations: 5721)

ActionView::Template::Error (content_type delegated to attachment, but attachment is nil):
    12: </div><!--end containerHeader-->
    13: 
    14: <div class="articleImage">
    15: <%= @article.article_image %>
    16: </div><!--endArticleImage-->
    17: 
    18: <p>

app/views/articles/show.html.erb:15
Started GET "/articles/wewew/edit" for ::1 at 2020-05-14 15:05:57 -0400
Processing by ArticlesController#edit as HTML
  Parameters: {"id"=>"wewew"}
`
santib commented 4 years ago

why don't you use a debugger (e.g. byebug) in the create action for the article and check if after the creation of the article the image is attached @article.article_image.attached?

guyeatspants commented 4 years ago

Man I’ve spent 2 weeks trying to get it to work I’m kinda fed up. This is the closest I’ve gottwn it to working.  I’ve created so many test apps, reinstalled everything, tried other gems, it’s sorta crazy.  I know it’s something silly. I mean I can see it literally save but it’s not getting attached. Now I believe the reason is havingarticle_image: :data at the end of my params, the article saving is still looking for the :article_image param for some reason.

Sent from Yahoo Mail for iPhone

On Thursday, May 14, 2020, 15:42, Santiago Bartesaghi notifications@github.com wrote:

why don't you use a debugger (e.g. byebug) in the create action for the article and check if after the creation of the article the image is attached @article.article_image.attached?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe.

santib commented 4 years ago

@diagraphic here you have a working example with code similar as yours https://github.com/santib/active-storage-base64-examples

More specifically this is the commit you need to check out https://github.com/santib/active-storage-base64-examples/commit/c1404b3ba5d5416ac3930ba57e7901e620632c79 in the last part of the conversation I noticed that you were sending the params incorrectly. name="article[article_image]" should have been name="article[article_image][data]"

Let me know if you have any question