0

我有一个 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 如何解决这个问题?

4

3 回答 3

1

您传递给的名称belongs_to应该是单数:

belongs_to :post
belongs_to :tag

编辑

此外,模型应命名为PostsTag. ActiveRecord 期望所有模型名称都是单数的,并且与表名的复数匹配。确保您的表名是“posts_tags”。

于 2012-08-30T13:48:16.807 回答
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_idtag_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

此方法的文档提供了有关命名连接表和优化性能的更多信息。

于 2012-08-30T14:15:37.877 回答
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 %>
于 2012-08-30T14:27:46.060 回答