Rails ActiveAdmin form for many-to-many relationship via junction table does not work

In my Rails application BlogPosts and BlogCategories, I use the BlogPostCategorization table to combine them. So,

class BlogCategory < ActiveRecord::Base
  attr_accessible :name, :created_at, :updated_at, :blog_post_id
  validates :name, presence: true, uniqueness: true
  has_many :blog_post_categorizations
  has_many :blog_posts, :through => :blog_post_categorizations
  accepts_nested_attributes_for :blog_posts, allow_destroy: true
end
class BlogPost < ActiveRecord::Base

  attr_accessible :body, :created_at, :updated_at, :image_url, :title
  validates :body, :image_url, :title, presence: true
  validates :title, uniqueness: true
  has_many :blog_post_categorizations
  has_many :blog_categories, :through => :blog_post_categorizations
  accepts_nested_attributes_for :blog_categories, allow_destroy: true
end
class BlogPostCategorization < ActiveRecord::Base
  belongs_to :blog_post
  belongs_to :blog_category
end

      

Now through ActiveAdmin, I want to be able to create a new blog post and create categories for that blog post. I have

form do |f|
    f.semantic_errors *f.object.errors.keys
    f.inputs "Blog Post" do
      f.input :title
      f.input :body, as: :html_editor
      f.input :image_url
    end
    f.inputs "Blog Categories" do
      f.has_many :blog_post_categorizations do |s|
        s.input :blog_category
      end
    end
    f.actions
end

      

But when I try to access the active admin page for a new blog post, I get a rails error saying "undefined method` new_record?" for nil: NilClass "on the line where

f.has_many: blog_post_categorizations do | s |

What am I doing wrong / missing?

Also, below is the blog_category data that is sent in the params hash of the POST request

"blog_categories_attributes"=>{"1408936652467"=>{"name"=>"cooking"}, "1408936656066"=>{"name"=>"eat"}}

      

+3


source to share


1 answer


I think this part:

f.inputs "Blog Categories" do
  f.has_many :blog_post_categorizations do |s|
    s.input :blog_category
  end
end

      

it should be:

f.inputs "Blog Categories" do
  f.has_many :blog_categorys do |s|
    s.input :name
  end
end

      


EDIT

Considering your other question on this matter, I would recommend (hopefully) a good workaround. Since strong_parameters are used by default in Rails 4 and up, and you are on Rails 3.2.17, let's make your application use it. So there are steps:

  • install gem 'strong_parameters'

    ;

  • set to false config.active_record.whitelist_attributes

    in config/application.rb

    ;

  • include ActiveModel::ForbiddenAttributesProtection

    in models BlogPost

    and BlogCategory

    ;
  • get rid of all calls attr_accessible

    .

After doing all this, you can whitelist all parameters in the private method, for example:



private

def blog_post_params
  params.require(:blog_post).permit(#all the params here)
end

      

And in #create action use BlogPost.new(blog_post_params)

(same in other models where you use the included module). Now you can take advantage of strong parameters.

In ActiveAdmin BlogPost

select the whitelist of all allowed options as:

permit_params :body, :created_at, :updated_at, :image_url, :title, blog_categories_attributes: [:id, :name, :_destroy, :blog_post_id]

      

and in the controller

controller do 
  def permitted_params 
    params.permit blog_posts: [:body, :created_at, :updated_at, :image_url, :title, blog_categories_attributes: [:id, :name, :_destroy, :blog_post_id]]
  end 
end

      

A more accurate look at the use of strong_pairs in the documentation. And also double check for typos / wrong names / underscores (because I was assuming some stuff).

Good luck!

+5


source







All Articles