【问题标题】:Rails 4 many to many association not workingRails 4多对多关联不起作用
【发布时间】:2013-10-20 01:43:53
【问题描述】:

Ruby on rails 新手在这里。尝试创建一个初学者博客应用程序,但我的模型之间存在多对多关联问题。

我有 2 个模型 - Post、Category,它们之间存在多对多关联。

我的问题:当我创建新帖子时,帖子被保存,但帖子类别关联没有保存在 categories_posts 表中。

我的代码如下。

感谢您对此的意见。

post.rb

class Post < ActiveRecord::Base
  validates_presence_of :title, :body, :publish_date
  belongs_to :user
  has_and_belongs_to_many :categories
end

category.rb

class Category < ActiveRecord::Base
  validates_presence_of :name
  has_and_belongs_to_many :posts
end

categories_posts.rb

class CategoriesPosts < ActiveRecord::Base
end

迁移 - create_posts.rb

class CreatePosts < ActiveRecord::Migration
  def change
    create_table :posts do |t|
     t.string :title
     t.text :body
     t.date :publish_date
     t.integer :user_id

     t.timestamps
    end
  end
end 

迁移 - create_categories.rb

class CreateCategories < ActiveRecord::Migration
  def change
    create_table :categories do |t|
      t.string :name
      t.timestamps
    end 
  end
end

迁移 - create_categories_posts.rb

class CreateCategoriesPosts < ActiveRecord::Migration
  def change
    create_table :categories_posts do |t|
      t.integer :category_id
      t.integer :post_id
      t.timestamps
    end
  end
end

后控制器 - 创建和新方法

#GET /posts/new
def new
  @post = Post.new
end

def create
  @post = Post.new(post_params)

  #User id is not a form field and hence is not assigned in the view. It is assigned when control is transferred back here after Save is pressed
  @post.user_id = current_user.id

  respond_to do |format|
    if @post.save
      format.html { redirect_to @post, notice: 'Post was successfully created.' }
      format.json { render action: 'show', status: :created, location: @post }
    else
      format.html { render action: 'new' }
      format.json { render json: @post.errors, status: :unprocessable_entity }
    end
  end
end

帖子视图(用于创建新帖子):

<%= simple_form_for @post, :html => { :class => 'form-horizontal' } do |f| %>
  <%= f.input :title %>
  <%= f.input :body %>
  <%= f.input :publish_date %>
  <%= f.association :categories, :as => :check_boxes %>
  <div class="form-actions">
    <%= f.button :submit, :class => 'btn-primary' %>
    <%= link_to t('.cancel', :default => t("helpers.links.cancel")),
            posts_path, :class => 'btn' %>
  </div>
<% end %>

谢谢, 迈克

【问题讨论】:

标签: ruby-on-rails ruby associations ruby-on-rails-4 has-and-belongs-to-many


【解决方案1】:

使用has_and_belongs_to_many 关联时,您需要在连接表上使用唯一索引。您的迁移应如下所示:

class CreateCategoriesPosts < ActiveRecord::Migration
  def change
    create_table :categories_posts do |t|
      t.integer :category_id
      t.integer :post_id
      t.timestamps
    end
    add_index :categories_posts, [:category_id, :post_id]
  end
end

您还可以摆脱 CategoriesPost 模型,仅当您想要实现 :has_many, :through 关联时才需要该模型。这应该可以回答您的问题。


为了彻底一点,如果您想将 :has_many, :through 关联与 CategoriesPost 模型一起使用,您可以这样实现:

class Post < ActiveRecord::Base
  has_many :categoriesposts
  has_many :categories, :through => :categoriesposts
end
class Category < ActiveRecord::Base
  has_many :categoriesposts
  has_many :posts, :through => :categoriesposts
end
class CategoriesPost < ActiveRecord::Base
  belongs_to :post
  belongs_to :category
end

如果你愿意,实现这个方法可以让你添加更多的属性到你的 categorypost 模型中。

【讨论】:

  • 我认为他在做 HABTM,而不是 has-many :through。我认为你应该改变你的答案,因为它是正确的(他需要更新他的加入模型),但因为上下文可能会产生误导
【解决方案2】:

在第一个答案的基础上,您需要将关联放入您的连接模型(CategoriesPosts)中,如下所示:

Class CategoriesPosts  < ActiveRecord::Base
    belongs_to :category
    belongs_to :post
End

【讨论】:

  • @Rick Pech 和 Antony 感谢您的意见。根据您的建议,更新 Post 和 Category 模型以分别使用 has_many :categories, :through => :categoriesposts 和 has_many :posts, :through => :categoriesposts。现在,当我尝试创建新帖子时,出现“未初始化的常量 Post::Categoriespost”错误。报错截图如下:imgur.com/a/BPD9k
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-06
  • 1970-01-01
  • 1970-01-01
  • 2014-11-27
  • 1970-01-01
相关资源
最近更新 更多