添加标签,我得到错误:
SQLite3 :: SQLException:没有这样的列:taggings.available_work_id: SELECT“tags”。* FROM“tags”INNER JOIN“taggings”ON“tags”。“id”= “taggings”。“tag_id”WHERE“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
答案 0 :(得分: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。