Search code examples
ruby-on-railsruby-on-rails-4has-manybelongs-to

Rails 4 belongs_to/has_many relationship not working


I've managed to get a few HABTM relationships set up without any problems, but for some reason I can't make a belongs_to/has_many relationship record the values.

  1. An Article belongs_to a Type (news, editorial, chronicle, etc.)
  2. A Type has_many Articles
  3. Schema.db shows the type_id integer column, the models use belongs_to and has_many and a drop down of article types appears in the form on the new/edit article pages.
  4. But on choosing a type from the drop down (e.g. 'chronicle'), it says it creates or edits the article successfully but does not register the link between the article and 'chronicle'. On going back to edit the same article, the drop down just shows the top type ('analysis'), not 'chronicle'.

So not sure where I'm going wrong. Here are all the relevant bits, starting with the database.

From schema.db:

create_table "articles", force: :cascade do |t|
  t.string   "headline"
  t.string   "lede"
  t.text     "body"
  t.datetime "created_at", null: false
  t.datetime "updated_at", null: false
  t.integer  "type_id"
end

create_table "types", force: :cascade do |t|
  t.string   "name"
  t.datetime "created_at", null: false
  t.datetime "updated_at", null: false
end

Then the models:

class Article < ActiveRecord::Base
  has_and_belongs_to_many :categories
  has_and_belongs_to_many :regions
  has_and_belongs_to_many :stories
  belongs_to :type
end

class Type < ActiveRecord::Base
  has_many :articles
end

And the articles controller:

# GET /articles/new
  def new
    @article = Article.new
    @regions = Region.all.order(:region)
    @categories = Category.all.order(:category)
    @stories = Story.all.order(:story)
    @types = Type.all.order(:name)
  end

# GET /articles/1/edit
  def edit
    @regions = Region.all.order(:region)
    @categories = Category.all.order(:category)
    @stories = Story.all.order(:story)
    @types = Type.all.order(:name)
  end

# POST /articles
# POST /articles.json
 def create
    @article = Article.new(article_params)

 respond_to do |format|
  if @article.save
    format.html { redirect_to @article, notice: 'Article was successfully created.' }
    format.json { render :show, status: :created, location: @article }
  else
    format.html { render :new }
    format.json { render json: @article.errors, status: :unprocessable_entity }
  end
  end
 end

/* …and then at the bottom… */

def article_params
  params.require(:article).permit(:headline, :lede, :body, :category_ids => [], :region_ids => [], :story_ids => [], :type_id => [])
end

And finally in the articles form:

<strong>Type:</strong> <%= f.collection_select :type_id, @types, :id, :name %>

Any ideas?


Solution

  • You need to change the article_params to below

    def article_params
      params.require(:article).permit(:headline, :lede, :body, :type_id, :category_ids => [], :region_ids => [], :story_ids => [])
    end
    

    Notice the change :type_id => [] to :type_id