dgreen22
dgreen22

Reputation: 398

Updating nested fields_for and collection_select in Rails

Really stumped here. I'm trying to get my form to update the categories on the edit form. Problem is, everything in my form updates when submitted except the categories. It ends up inserting the new category chosen like it's going through the create method instead of the update method, so when the edit form is shown again after submission, it keeps doubling the fields of categories. 1, then 2, then 4, then 8, etc. after each submission. Please please help anyone. Appreciate it.

views/blog_posts/edit.html.erb

<div class="col-md-6 col-md-offset-3 blog-submit">
            <%= form_for @blog_post do |b| %>


             <%= b.label :title %>
             <%= b.text_field :title %><br>

                <%= b.fields_for :categorizations do |cat| %>
                <%= cat.label :category_name, "Category 1" %>
                <%= cat.collection_select(:category_id, Category.all, :id, :category_name, {blank: "Select Category"}) %>
                <%= link_to "Add Categories", new_category_path %>
                  <br>
                <% end %>

                <%= b.submit "Submit", class: "btn btn-primary" %>
          <% end %>
        </div>

Blog_post controller:

class BlogPostsController < ApplicationController
    protect_from_forgery
    before_action :authenticate_admin!, only: [:new, :edit]

    def index
      @blog_posts = BlogPost.order(id: :desc)
    end

    def new
      @blog_post = BlogPost.new
      @blog_post.categorizations.build.build_category
      @blog_post.categories.build
    end

    def edit
         @blog_post = BlogPost.find(params[:id])
    end

    def create
      @blog_post = BlogPost.new(blog_post_params)
      respond_to do |format|
          if @blog_post.save
            format.html { redirect_to @blog_post, notice: 'Your blog was submitted successfully' }
            format.json { render :show, status: :created, location: @blog_post }
          else
            format.html { render :new }
            format.json { render json: @blog_post.errors, status: :unprocessable_entity }
          end
        end
        puts @blog_post.errors.inspect
    end

    def update
        @blog_post = BlogPost.find(params[:id])
        if @blog_post.update_attributes(blog_post_params)
          render 'show'  
        else
          render 'edit'
        end
    end

    def show
        @blog_post = BlogPost.find(params[:id])

    end



private

  def blog_post_params
    params.require(:blog_post).permit(:title, :content, :posted_by, :comments, :blog_pic, {categorizations_attributes: [:category_id, :category_name]})
  end

end

models:

class BlogPost < ApplicationRecord
    has_many :categorizations
    has_many :categories, :through => :categorizations
    accepts_nested_attributes_for :categorizations
    has_many :comments
    mount_uploader :blog_pic, BlogPicUploader
end

class Categorization < ApplicationRecord
    belongs_to :blog_post
    belongs_to :category
end

class Category < ApplicationRecord
    has_many :categorizations
    has_many :blog_posts, :through => :categorizations 
end

Upvotes: 2

Views: 1305

Answers (1)

sreeraj nyros
sreeraj nyros

Reputation: 979

Add id in blog_post_params as shown below. This will work for you.

def blog_post_params
    params.require(:blog_post).permit(:title, :content, :posted_by, :comments, :blog_pic, {categorizations_attributes: [:id,:category_id, :category_name]})
  end

Upvotes: 2

Related Questions