Home > Net >  Tagify with Rails 7 combining JSON tags after submit
Tagify with Rails 7 combining JSON tags after submit

Time:08-24

I'm using @yairEO/tagify on my Rails 7 app. I have it almost working. It will save to the database as valid JSON. If I submit the form using tagify with 3 tags, for example tag1, tag2, tag3, after I go back to the form to edit, tagify shows these 3 separate tags combined into one single tag.

From the database:

[
  {
    "value":"tag1"
  },
  {
    "value":"tag2"
  },
  {
    "value":"tag3"
  }
]

From irb recipe.tags:

[
  {
    "value"=>"tag1"
  },
  {
    "value"=>"tag2"
  },
  {
    "value"=>"tag3"
  }
]

Before submitting: before

After submitting: after

Things quickly get out of control when adding to the bad response. Before submitting: enter image description here

After submitting: enter image description here

application.js

import Tagify from "@yaireo/tagify"

document.addEventListener('turbo:load', (event) => {
  new Tagify(document.querySelector('#recipe_tags'));
});

recipes_controller.rb

def update
  @recipe.update(tags: JSON.parse(params[:recipe][:tags]))

  if @recipe.update(recipe_params)
    redirect_to @recipe
  else
    render :edit, status: :unprocessable_entity
  end
end
def recipe_params
  params[:recipe][:tags] = JSON.parse(params[:recipe][:tags])
  params.require(:recipe).permit(
    :title, :subtitle, :tags
  )
end

edit.html.erb

<div>
  <%= form.label :tags %><br>
  <%= form.text_field :tags %>
  <% recipe.errors.full_messages_for(:tags).each do |message| %>
    <div><%= message %></div>
  <% end %>
</div>

schema.rb

  create_table "recipes", force: :cascade do |t|
    t.string "title"
    t.string "subtitle"
    t.jsonb "tags", default: {}, null: false
    t.index ["user_id"], name: "index_recipes_on_user_id"
  end

Edit:

Removing @recipe.update(tags: JSON.parse(params[:recipe][:tags])) and params[:recipe][:tags] = JSON.parse(params[:recipe][:tags]) from the controller results in the data showing correctly. However, a 500 error is thrown:

Completed 500 Internal Server Error in 19ms (ActiveRecord: 10.6ms | Allocations: 4899)
NoMethodError (undefined method `join' for "[{\"value\":\"tag1\"},{\"value\":\"tag2\"},{\"value\":\"tag3\"}]":String):

Despite the 500 error, the data will still save to the database and will show properly on refresh. I guess the question now becomes, why is there a 500 error and what can be done to resolve it?

CodePudding user response:

It's always the small dumb stuff that gets overlooked and takes way too many hours to notice!

The meta-tags gem was being used in the recipes_controller's show method like this: set_meta_tags keywords: @recipe.tags.join(', ') unless @recipe.tags.empty?

This was causing the error when submitting the form because the user was being redirected to the show view which contained this erroneous code.

As I described in the original question, on a refresh (of the edit page), everything worked as expected -- this is because the broken code from the controller wasn't being called.

  • Related