Antonin Mrchd Antonin Mrchd - 3 days ago 5
Ruby Question

Could not find table 'tags_travels' rails

I have a problem, I want to create an hashtags system, but when I run my code, and when I want to create a travel that contain hashtags I have this error :

ActiveRecord::StatementInvalid in TravelsController#create
Could not find table 'tags_travels'


Here is my travel.rb

class Travel < ApplicationRecord
has_many :posts
belongs_to :user
has_and_belongs_to_many :tags

#after / before create
after_create do
travel = Travel.find_by(id: self.id)
sh = self.hashtags.scan(/#\w+/)
sh.uniq.map do |s|
tag = Tag.find_or_create_by(name: s.downcase.delete('#'))
travel.tags << tag
end
end

before_update do
travel = Travel.find_by(id: self.id)
travel.tags.clear
sh = self.hashtags.scan(/#\w+/)
sh.uniq.map do |s|
tag = Tag.find_or_create_by(name: s.downcase.delete('#'))
travel.tags << tag
end
end
end


my tag.rb

class Tag < ApplicationRecord
has_and_belongs_to_many :travels
end


the schema.rb file (just table concerned) :

create_table "tags", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end

create_table "topics", force: :cascade do |t|
t.string "title"
t.string "text"
t.string "end_date"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "post_id"
end

create_table "travels", force: :cascade do |t|
t.string "name"
t.string "trip_type"
t.string "description"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "user_id"
t.string "hashtags"
end

create_table "travels_tags", id: false, force: :cascade do |t|
t.integer "travel_id"
t.integer "tag_id"
t.index ["tag_id"], name: "index_travels_tags_on_tag_id"
t.index

["travel_id"], name: "index_travels_tags_on_travel_id"
end


Someone has a solution ? Thank !

Answer

Rails looks for join tables in a specific syntax. Its trying to find tags_travles but uouve created it with travels_tags.

Change your model associations to specify the join table.

has_and_belongs_to_many :travels, :join_table => :travels_tags

And

has_and_belongs_to_many :tags, :join_table => :travels_tags

Heres some info from the docs to help explain the defsult behaviour for join table naming.

"By default, the name of the join table comes from the union of the first two arguments provided to create_join_table, in alphabetical order."

http://edgeguides.rubyonrails.org/active_record_migrations.html#creating-a-join-table

Comments