Home > OS >  How to create an object with relationship?
How to create an object with relationship?

Time:10-08

i have two models, i want to create an object Theme, so far i can create Product but i can not create Theme, i dont know why

class Product < ApplicationRecord 
  has_many :themes 
end

and

class Theme < ApplicationRecord
  belongs_to :products
  
end

with this function i am trying to create

  def create
    @product = Product.find(3)
    @theme = Theme.create(title:'theme' ,description:'description',  products_id: @product)
  end

my migrations are:

class CreateProducts < ActiveRecord::Migration[7.0]
  def change
    create_table :products do |t|
      t.string :name
      t.string :description
      t.integer :price

      t.timestamps
    end
  end
end

and

class CreateThemes < ActiveRecord::Migration[7.0]
  def change
    create_table :themes do |t|
      t.string :title
      t.string :description
      t.belongs_to :products, null: false, foreign_key: true

      t.timestamps
    end
  end
end

i am getting this warning error with this sentence

@theme = Theme.create(title:'theme' ,description:'description',  products_id: @product.id)

this error:

"#<NameError: Rails couldn't find a valid model for Products association. Please provide the :class_name option on the association declaration. If :class_name is already provided, make sure it's an ActiveRecord::Base subclass.\n\n raise NameError, msg\n ^^^^^>",

CodePudding user response:

Firstly your association and migration are wrong. By convention when you use belongs_to, you need to use singular, not plural

To fix schema, you need to create new migration (usually changing old migrations is bad idea)

change_table :themes do |t|
  t.remove_belongs_to :products, null: false, foreign_key: true
  t.belongs_to :product, null: false, foreign_key: true
end

This will create product_id and delete products_id column in themes table

Than change association to

class Theme < ApplicationRecord
  belongs_to :product
end

And finally to create theme of specific product:

product.themes.create(title: 'theme', description: 'description')

product_id will assign automatically, you don't need specify it

  • Related