我有一个ActiveRecord类:
class Post < ActiveRecord::Base
has_many :posts_tags
has_many :tags, :through => :posts_tags
end
class Tag < ActiveRecord::Base
has_many :posts_tags
has_many :posts, :through => :posts_tags
end
class PostsTags < ActiveRecord::Base
belongs_to :posts
belongs_to :tags
end
当我想获得帖子标签时:
<% @posts = Post.all %>
<% @posts.each do |post| %>
<% if post.tags.count != 0 %>
<div class="post-tags">
<% post.tags.each do |tag| %>
<span><%= tag.name%></span>
<%end%>
</div>
<%end%>
<% end %>
我收到错误uninitialized constant Post::PostsTag
我该如何解决这个问题?
答案 0 :(得分:1)
您传递给belongs_to
的名称应该是单数:
belongs_to :post
belongs_to :tag
修改强>
此外,该模型应命名为PostsTag
。 ActiveRecord期望所有模型名称都是单数的,并且与多个表名匹配。确保您的表名是'posts_tags'。
答案 1 :(得分:1)
引用ActiveRecord文档:
选择构建多对多关系的方式并不总是很简单。如果您需要将关系模型作为自己的实体使用,请使用has_many:through。在使用旧模式时或者从不直接使用关系本身时,请使用has_and_belongs_to_many。
由于您似乎只使用PostsTags
类进行加入,因此您应该考虑切换到has_and_belongs_to_many
class Post < ActiveRecord::Base
has_and_belongs_to_many :tags # foreign keys in the join table
end
class Tag < ActiveRecord::Base
has_and_belongs_to_many :posts # foreign keys in the join table
end
您应该已经有一个posts_tags
表格,其中包含post_id
课程中的tag_id
和PostsTags
列。如果没有,那么你需要创建一个。除非在声明关系时为连接表指定自定义名称,否则表必须命名为posts_tags
。可能的迁移可能如下所示:
class CreatePostsTagsJoinTable < ActiveRecord::Migration
def change
create_table :posts_tags, :id => false do |t|
t.integer :post_id
t.integer :tag_id
end
end
end
然后您应该删除app/models/posts_tags.rb
文件,因为has_and_belongs_to_many
关系,“[t]他连接表不应该有主键或与之关联的模型。” - ActiveRecord :: Associations :: ClassMethods
documentation for this method提供了有关命名连接表和优化性能的更多信息。
答案 2 :(得分:1)
你有多对多的关系,你应该阅读A Guide to Active Record Associations
你所拥有的并不是很困难,但确实需要一些研究。作为一个简单的规则:如果您要使用关联(例如,您想要将描述存储到PostTag),请使用以下代码。如果不是:请使用之前帖子中已涵盖的has_and_belongs_to_many
。在代码下方,使用迁移,模型和视图:
class Post < ActiveRecord::Base
has_many :post_tags
has_many :tags, :through => :post_tags
end
class Tag < ActiveRecord::Base
has_many :post_tags
has_many :posts, :through => :post_tags
end
class PostTag < ActiveRecord::Base
belongs_to :post
belongs_to :tag
end
您的迁移应该如下所示:
class CreateTables < ActiveRecord::Migration
def self.up
create_table :tags do |t|
# some other attributes here
t.timestamps
end
create_table :posts do |t|
# some other attributes here
t.timestamps
end
create_table :post_tags do |t|
# some other attributes here
t.references :post
t.references :tag
t.timestamps
end
end
def self.down
drop_table :tags
drop_table :posts
drop_table :post_tags
end
end
您的观点应如下所示:
<% @posts = Post.all %>
<% @posts.each do |post| %>
<% if post.tags.any? %>
<div class="post-tags">
<% post.tags.each do |tag| %>
<span><%= tag.name %></span>
<%end%>
</div>
<%end%>
<% end %>