2015-04-07 2 views
0

У меня есть many_to_many связь между Categories и Articles, используя has_and_belongs_to_many в Rails 4 приложения: сВозникли проблемы рендеринга флажков в many_to_many ассоциации Rails 4

Вот соответствующие миграции и классы:

class CategoriesArticles < ActiveRecord::Migration 
    def change 
    create_table :categories_articles, id: false do |t| 
     t.belongs_to :category, index: true 
     t.belongs_to :article, index: true 
    end 
    add_index :categories_articles, [: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 index 
    if user_signed_in? 
     @articles = current_user.article_feed 
     # TODO: if there are too few articles on a user's feed, we want to display more articles 
    else 
     @articles = Article.all 
    end 
    @articles = @articles.page(params[:page] || 1).per(12) 
    respond_with(@articles) 
    end 

    def show 
    respond_with(@article) 
    end 

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

    def edit 
    if current_user.articles.find_by_id(params[:id]).nil? 
     flash[:notice] = "You do not have permission to edit this article." 
     redirect_to @article 
    end 
    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 

    def destroy 
    if @article 
     @article.destroy 
     flash[:notice] = "Article successfully destroyed." 
    else 
     flash[:notice] = "You do not have permission to delete this article." 
    end 
    # TODO: change this to another redirect location 
    redirect_to root_path 
    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 %> 

Однако это erroring для меня , в частности линии:

<% @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>. Как это исправить? Благодарю.

+0

Вы используете вложенную форму (http://railscasts.com/episodes/196-nested-model-form-part-1?view=asciicast). Итак, прочитайте подробности. – Emu

ответ

0

Я отмечаю ваш присоединиться к таблице называется

create_table :categories_articles, id: false do |t| 

Имя должно быть в алфавитном порядке.

create_table :articles_categories, id: false do |t| 

Мой выбор заключается в том, что Rails не может найти вашу таблицу соединений. Это означает, что форма, когда она вызывает @ article.categories, не может найти то, что ей нужно. То же самое произойдет, если вы вызываете @ category.articles (то есть: возможность найти таблицу соединений не связана с произвольным порядком объектов).

Смотрите мой ответ на this question

Смежные вопросы