4

Ruby on rails初心者です。スターター ブログ アプリを作成しようとしていますが、モデル間の多対多の関連付けに問題があります。

私は 2 つのモデルを持っています - 互いに多対多の関連を持つ投稿、カテゴリ。

私の問題: 新しい投稿を作成すると、投稿は保存されますが、投稿とカテゴリの関連付けは、category_posts テーブルに保存されません。

私のコードは以下の通りです。

これについてのご意見に感謝します。

post.rb

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

カテゴリ.rb

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

カテゴリ_投稿.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

Post Controller - create および new メソッド

#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 %>

ありがとう、マイク

4

2 に答える 2

14

関連付けを使用する場合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。それはあなたの質問に答えるはずです。


徹底的に言うと、 CategoriesPost モデルとの関連付けを使用したい場合は、次:has_many, :throughのように実装できます。

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 モデルにさらに属性を追加できます。

于 2013-10-20T07:04:46.867 に答える