2015-06-21 4 views
2

Добавление тегов и я получаю эту ОШИБКА:Добавление тегов в Rails

SQLite3 :: SQLException: нет такой колонки: taggings.available_work_id:. SELECT "метки" * FROM "метки" INNER JOIN " taggings "ON" tags "." id "= " taggings "." tag_id "ГДЕ" taggings "." available_work_id "=?

Available_work.index.html

<tbody> 
    <% @available_works.each do |available_work| %> 
     <tr> 
     <td><%= available_work.title %></td> 
     <td><%= available_work.description.html_safe %></td> 
     <td>Tags: <%= raw available_work.tags.map(&:name).map { |t| link_to t, tag_path(t) }.join(', ') %></td> 
     <td><%= image_tag available_work.image_url(:thumb) %></td> 
     <td><%= link_to 'Show', available_work %></td> 
     <td><%= link_to 'Edit', edit_available_work_path(available_work) %></td> 
     <td><%= link_to 'Destroy', available_work, method: :delete, data: { confirm: 'Are you sure?' } %></td> 
     </tr> 
    <% end %> 
    </tbody> 
    </table> 

Available_work.rb

class AvailableWork < ActiveRecord::Base 
    attr_accessor :image, :remote_image_url, :tag_list 
    mount_uploader :image, ImageUploader 
    has_many :taggings 
    has_many :tags, through: :taggings 


    def self.tagged_with(name) 
     Tag.find_by_name!(name).available_work 
    end 

    def self.tag_counts 
     Tag.select("tags.*, count(taggings.tag_id) as count"). 
     joins(:taggings).group("taggings.tag_id") 
    end 

    def tag_list 
     tags.map(&:name).join(", ") 
    end 

    def tag_list=(names) 
     self.tags = names.split(",").map do |n| 
     Tag.where(name: n.strip).first_or_create! 
     end 
    end 
    end 

Tag.rb

class Tag < ActiveRecord::Base 
has_many :taggings 
has_many :available_work, through: :taggings 
end 

Taggings.rb

class Tagging < ActiveRecord::Base 
belongs_to :tag 
belongs_to :availble_work 
end 

Схема

create_table "available_works", force: :cascade do |t| 
    t.string "title" 
    t.string "description" 
    t.string "tags" 
    t.string "image" 
    t.datetime "created_at", null: false 
    t.datetime "updated_at", null: false 
    t.string "taggings" 
    end 

ответ

1

Вы бы добавить available_work_id колонка в таблице -осна-. Однако было бы лучше создать полиморфное отношение к помеченному объекту, хотя вы можете использовать теги больше, чем модель AvailableWork.

EDITED. Там, где в моем примере несколько ошибок. Вот полная версия работает:

class Tag < ActiveRecord::Base 
    has_many :taggings 

    def self.tag_counts 
    select("tags.*, count(taggings.tag_id) as count") 
     .joins(:taggings) 
     .group("taggings.tag_id") 
    end 
end 

class Tagging < ActiveRecord::Base 
    belongs_to :tag 
    belongs_to :tagged, 
      polymorphic: :true, 
      inverse_of: :taggings 
end 

class AvailableWork < ActiveRecord::Base 
    has_many :taggings, as: :tagged 
    has_many :tags, through: :taggings 

    def self.tagged_with(name) 
    # We have to do this in two queries since Rails does not 
    # do joins on polymorphic relations. 
    ids = Tagging.where(tagged_type: self.name) 
      .joins(:tag) 
      .where(tags: { name: name }).pluck(:tagged_id) 
    find(ids) 
    end 

    def self.tag_counts 
    Tag.tag_counts.where(taggings: { tagged_type: self.name }) 
    end 

    def tag_list 
    tags.map(&:name).join(", ") 
    end 

    def tag_list=(names) 
    self.tags = names.split(",").map do |n| 
     Tag.where(name: n.strip).first_or_create! 
    end 
    end 
end 

ActiveRecord::Schema.define(version: 20150621234032) do 
    create_table "available_works", force: :cascade do |t| 
    t.string "title" 
    t.string "description" 
    t.string "image" 
    t.datetime "created_at", null: false 
    t.datetime "updated_at", null: false 
    end 

    create_table "taggings", force: :cascade do |t| 
    t.integer "tag_id" 
    t.integer "tagged_id" 
    t.string "tagged_type" 
    t.datetime "created_at", null: false 
    t.datetime "updated_at", null: false 
    end 

    add_index "taggings", ["tag_id"], name: "index_taggings_on_tag_id" 
    add_index "taggings", ["tagged_id"], name: "index_taggings_on_tagged_id" 

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

<table> 
    <tbody> 
    <% @available_works.each do |available_work| %> 
    <tr> 
     <td><%= available_work.title %></td> 
     <td><%= available_work.description.try(:html_safe) %></td> 
     <td>Tags: <%= available_work.tag_list %></td> 
     <td><%#= image_tag available_work.image_url(:thumb) %></td> 
     <td><%= link_to 'Show', available_work %></td> 
     <td><%= link_to 'Edit', edit_available_work_path(available_work) %></td> 
     <td><%= link_to 'Destroy', available_work, method: :delete, data: { confirm: 'Are you sure?' } %></td> 
    </tr> 
    <% end %> 
    </tbody> 
</table> 

Обратите внимание, что я прокомментировал часть изображений, чтобы сэкономить время, поскольку это не имеет прямого отношения к вопросу.

Приложение Rails, которое я создал для ответа на вопрос, можно получить по адресу: https://github.com/maxcal/playground/tree/adding-tags-in-rails.

+0

Спасибо за вашу помощь @maxcal .. Я следил за вашими предложениями, но получаю сообщение об ошибке. 'undefined method' tag_list 'для nil: NilClass Теги: <% = raw @ available_work.tag_list.map {| t | link_to t, tag_path (t)} .join (',')%> –

+0

Вы только что скопировали/ввели класс AvailableWork из моего ответа прямо в ваше приложение? – max

+0

Я сделал, кроме класса AvailableWork

Смежные вопросы