2015-04-16 68 views
0

我有ArticlesCategories之間的many_to_many協會,在Rails 4應用程序中使用has_and_belongs_to_many無法渲染Rails 4 many_to_many關聯中的複選框?

這裏有相應的遷移和類:

class CategoriesArticles < ActiveRecord::Migration 
    def change 
    create_table :articles_categories, id: false do |t| 
     t.belongs_to :category, index: true 
     t.belongs_to :article, index: true 
    end 
    add_index :articles_categories, [:category_id, :article_id] 
    end 
end 

class Category < ActiveRecord::Base 
    has_and_belongs_to_many :articles 
end 

class Article < ActiveRecord::Base 
    has_and_belongs_to_many :categories 
end 

當用戶創建一個新的文章,我只是想給他或她選擇他/她想要與新文章相關聯的類別的選項。我希望用戶能夠用複選框選擇這些類別。

這裏的ArticlesController

class ArticlesController < ApplicationController 
    before_action :set_article, only: [:show, :edit, :update, :destroy] 
    before_action :authenticate_user!, only: [:new, :create, :edit, :destroy, :update] 
    before_action :verify_own_article, only: [:destroy] 
    respond_to :html 

    ... 

    def new 
    @categories = Category.all 
    @article = Article.new 
    respond_with(@article) 
    end 

    def create 
    # Creates article object with current_user_id, initial_comment, and URL 
    @article = current_user.articles.build(article_params) 

    # Uses Pismo (gem) to grab title, content, photo of URL 
    @article.populate_url_fields 
    if @article.save 
     flash[:success] = "Article created!" 

     # Might need to change the location of this redirect 
     redirect_to root_url 
    else 
     flash[:notice] = "Invalid article." 
     redirect_to new_article_path 
    end 

    end 

    def update 
    @article.update(article_params) 
    flash[:notice] = "Article successfully updated." 
    respond_with(@article) 
    end 

    private 
    def set_article 
     @article = Article.find(params[:id]) 
    end 

    def article_params 
     params.require(:article).permit(:url, :title, :datetime, :content, :photo, :initial_comment) 
    end 

    # Ensure that a signed in user can only delete articles that they have posted 
    def verify_own_article 
     @article = current_user.articles.find_by_id(params[:id]) 
    end 
end 

這裏的文章new.html.erb觀點:

<h1>New article</h1> 

<%= render 'form' %> 

<%= link_to 'Back', articles_path %> 

...和form部分:

<%= form_for(@article) do |f| %> 
    <% if @article.errors.any? %> 
    <div id="error_explanation"> 
     <h2><%= pluralize(@article.errors.count, "error") %> prohibited this article from being saved:</h2> 

     <ul> 
     <% @article.errors.full_messages.each do |message| %> 
     <li><%= message %></li> 
     <% end %> 
     </ul> 
    </div> 
    <% end %> 

    <div class="field"> 
    <%= f.label :url %><br> 
    <%= f.text_field :url %> 
    </div> 
    <div class="field"> 
    <%= f.label :initial_comment %><br> 
    <%= f.text_field :initial_comment %> 
    </div> 


    <% @categories.each do |t| %> 
    <div class="field"> 
     <%= f.label t.name %> 
     <%= f.check_box "categories[#{t.id}]" %> 
     <br /> 
    </div> 
    <% end %> 

    <div class="actions"> 
    <%= f.submit %> 
    </div> 
<% end %> 

然而,這示數爲我,特別是行:

<% @categories.each do |t| %> 
     <div class="field"> 
      <%= f.label t.name %> 
      <%= f.check_box "categories[#{t.id}]" %> 
      <br /> 
     </div> 
     <% end %> 

具體來說,它告訴我:

undefined method 'categories[1]' for #<Article:0x007f401193d520>當我試圖渲染New Article頁面。我該如何解決?謝謝。

回答

2

這是更好地使用,而不是試圖通過手工來創建這些複選框的Rails collection_check_boxes幫手。這個幫助程序已經創建了所有需要的參數/標記內容,以便添加或排除HABTM關係的項目。所以,你可能會改變您查看到包括以下內容:

<%= f.collection_check_boxes :categories_ids, @categories, :id, :name %> 

不要忘了你的強烈的參數聲明添加這個(因爲你必須接受所選擇的類別id和它們綁定到你的Article模型) :

params.require(:article).permit(
    :url, :title, :datetime, :content, 
    :photo, :initial_comment, categories_ids: [] 
) 

對於進一步定製(HTML造型或結構,每個複選框),請參閱完整的documentation

我希望它能幫助:)