Agile Web Development with Rails 7: [solved]

Hello everyone,

I am relatively new to rails. I am reading AWDWR 7.

I am at page 120, I have some questions and having some problems.

Questions:

  • In line_item model we create a relationship to product and cart models. Do we need a n x m relationship between product and cart models? Because of that we create the line_item model?

  • Also inside the product and cart models we have has_many :line_items. Where is these relationships inside our schema.rb? I don’t see any sql relationship? If we don’t have a sql relationship is it good way to create relationships in ruby?

Need help code debugging:

  • I think I am having some problem. inside the line_items_controller.rb in the create method at @line_item = @cart.line_items.build(product: product) it gives me error. Saying : ActiveModel::MissingAttributeError in LineItemsController#create
    can’t write unknown attribute product_id. Any helps solving this problem

Thank you @rubys for this book!

Have a great day!

Mert

  • In line_item model we create a relationship to product and cart models. Do we need a n x m relationship between product and cart models? Because of that we create the line_item model?

Yes. :slight_smile:

  • Also inside the product and cart models we have has_many :line_items. Where is these relationships inside our schema.rb? I don’t see any sql relationship? If we don’t have a sql relationship is it good way to create relationships in ruby?

The relationships are foreign keys defined in the line item, specifically product_id and cart_id.

What’s going on here is that belongs_to matches a foreign key defined on this model/table, and both has_one and has_many matches a foreign key defined on the referenced model/table.

If you are familiar with SQL, try running the command bin/rails console. And within the console type the following two commands:

product = Product.last
product.line_items

As you type these commands, you will see the SQL that was evaluated.

  • I think I am having some problem. inside the line_items_controller.rb in the create method at @line_item = @cart.line_items.build(product: product) it gives me error. Saying : ActiveModel::MissingAttributeError in LineItemsController#create
    can’t write unknown attribute product_id. Any helps solving this problem

Check app/models/line_item.rb. It should have the line belongs_to :product. Perhaps you have has_one :product there instead? The correct code should look like https://media.pragprog.com/titles/rails7/code/rails7/depot_f/app/models/line_item.rb

If you have has_one, what Rails will attempt to do is to update an attribute named line_item_id in the Product model/products table, and not find any such attribute defined.

Thank you for your response.

I think I found the problem, https://media.pragprog.com/titles/rails7/code/rails7/depot_f/db/schema.rb . This schema is different than my schema.rb. Mine doesn’t have foreign keys.

My schema.rb:

ActiveRecord::Schema[7.0].define(version: 2022_02_27_012811) do
  create_table "carts", force: :cascade do |t|
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

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

  create_table "products", force: :cascade do |t|
    t.string "title"
    t.text "description"
    t.string "image_url"
    t.decimal "price", precision: 8, scale: 2
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end
end

Your schema.rb

ActiveRecord::Schema[7.0].define(version: 2022_01_19_000003) do
  create_table "carts", force: :cascade do |t|
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

  create_table "line_items", force: :cascade do |t|
    t.integer "product_id", null: false
    t.integer "cart_id", null: false
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["cart_id"], name: "index_line_items_on_cart_id"
    t.index ["product_id"], name: "index_line_items_on_product_id"
  end

  create_table "products", force: :cascade do |t|
    t.string "title"
    t.text "description"
    t.string "image_url"
    t.decimal "price", precision: 8, scale: 2
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

  add_foreign_key "line_items", "carts"
  add_foreign_key "line_items", "products"
end

Which step do you think I missed? My models are exactly the same as your, maybe I forgot a migration?

It looks like your line_items are missing both a product and a cart. Those should have been added when you generated your scaffold in Iteration D2.

You can add them now with the following:

bin/rails generate migration AddProductAndCartToLineItems product:references cart:belongs_to