Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

has_many ActiveRecord though ActiveHash generates invalid SQL #323

Open
MoAI522 opened this issue Sep 21, 2024 · 1 comment
Open

has_many ActiveRecord though ActiveHash generates invalid SQL #323

MoAI522 opened this issue Sep 21, 2024 · 1 comment

Comments

@MoAI522
Copy link

MoAI522 commented Sep 21, 2024

Describe the bug

I can't retrieve ActiveRecord records from ActiveHash object when the ActiveHash is related to the ActiveRecord through another ActiveHash.

To Reproduce

  1. Create books table below.
# db/schema.rb

ActiveRecord::Schema[7.2].define(version: 2024_09_21_030534) do
  create_table "books", force: :cascade do |t|
    t.string "title"
    t.integer "author_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end
end

# test/fixtures/books.yml

one:
  title: MyString
  author_id: 1

two:
  title: MyString
  author_id: 1

  1. Execute bin/rails db:fixtures:load

  2. Create models below.

# app/models/book.rb

class Book < ApplicationRecord
  extend ActiveHash::Associations::ActiveRecordExtensions
  belongs_to :author
  delegate :country, to: :author
end
# app/models/author.rb

class Author < ActiveHash::Base
  include ActiveHash::Associations

  has_many :books
  belongs_to :country

  self.data = [
    { id: 1, name: 'Author A', country_id: 1 },
    { id: 2, name: 'Author B', country_id: 2 },
  ]
end
# app/models/country.rb

class Country < ActiveHash::Base
  include ActiveHash::Associations

  has_many :authors
  has_many :books, through: :authors

  self.data = [
    { id: 1, name: 'USA' },
    { id: 2, name: 'Japan' },
  ]
end
  1. Execute code below on rails console.
Country.find(1).books

Expected Behavior

Returns all Book records.(They are all have author_id=1, and the author relates to country 1.)

[#<Book:0x00007faef7873860
  id: 298486374,
  title: "MyString",
  author_id: 1,
  created_at: "2024-09-21 03:17:10.084083000 +0000",
  updated_at: "2024-09-21 03:17:10.084083000 +0000">,
 #<Book:0x00007faef7873720
  id: 980190962,
  title: "MyString",
  author_id: 1,
  created_at: "2024-09-21 03:17:10.084083000 +0000",
  updated_at: "2024-09-21 03:17:10.084083000 +0000">]

Actual Behavior

The output is below.

  Book Load (0.7ms)  SELECT "books".* FROM "books" WHERE "books"."country_id" = ? /* loading for pp */ LIMIT ?  [["country_id", 1], ["LIMIT", 11]]
An error occurred when inspecting the object: #<ActiveRecord::StatementInvalid: SQLite3::SQLException: no such column: books.country_id>
Result of Kernel#inspect: #<Book::ActiveRecord_Relation:0x00007fb3c5382ef0 @klass=Book(id: integer, title: string, author_id: integer, created_at: datetime, updated_at: datetime), @table=#<Arel::Table:0x00007fb3c53ff6a8 @name="books", @klass=Book(id: integer, title: string, author_id: integer, created_at: datetime, updated_at: datetime), @type_caster=#<ActiveRecord::TypeCaster::Map:0x00007fb3c572f2d8 @klass=Book(id: integer, title: string, author_id: integer, created_at: datetime, updated_at: datetime)>, @table_alias=nil>, @values={:where=>#<ActiveRecord::Relation::WhereClause:0x00007fb3c56d1cc8 @predicates=[#<Arel::Nodes::Equality:0x00007fb3c56d1d40 @left=#<struct Arel::Attributes::Attribute relation=#<Arel::Table:0x00007fb3c53ff6a8 @name="books", @klass=Book(id: integer, title: string, author_id: integer, created_at: datetime, updated_at: datetime), @type_caster=#<ActiveRecord::TypeCaster::Map:0x00007fb3c572f2d8 @klass=Book(id: integer, title: string, author_id: integer, created_at: datetime, updated_at: datetime)>, @table_alias=nil>, name="country_id">, @right=#<ActiveRecord::Relation::QueryAttribute:0x00007fb3c54bcb90 @name="country_id", @value_before_type_cast=1, @type=#<ActiveModel::Type::Value:0x00007fb3c5ec6938 @precision=nil, @scale=nil, @limit=nil>, @original_attribute=nil, @value=1, @_unboundable=nil, @value_for_database=1>>]>}, @loaded=nil, @predicate_builder=#<ActiveRecord::PredicateBuilder:0x00007fb3c572f210 @table=#<ActiveRecord::TableMetadata:0x00007fb3c572f238 @klass=Book(id: integer, title: string, author_id: integer, created_at: datetime, updated_at: datetime), @arel_table=#<Arel::Table:0x00007fb3c53ff6a8 @name="books", @klass=Book(id: integer, title: string, author_id: integer, created_at: datetime, updated_at: datetime), @type_caster=#<ActiveRecord::TypeCaster::Map:0x00007fb3c572f2d8 @klass=Book(id: integer, title: string, author_id: integer, created_at: datetime, updated_at: datetime)>, @table_alias=nil>, @reflection=nil>, @handlers=[[Set, #<ActiveRecord::PredicateBuilder::ArrayHandler:0x00007fb3c572f080 @predicate_builder=#<ActiveRecord::PredicateBuilder:0x00007fb3c572f210 ...>>], [Array, #<ActiveRecord::PredicateBuilder::ArrayHandler:0x00007fb3c572f0d0 @predicate_builder=#<ActiveRecord::PredicateBuilder:0x00007fb3c572f210 ...>>], [ActiveRecord::Relation, #<ActiveRecord::PredicateBuilder::RelationHandler:0x00007fb3c572f120>], [Range, #<ActiveRecord::PredicateBuilder::RangeHandler:0x00007fb3c572f170 @predicate_builder=#<ActiveRecord::PredicateBuilder:0x00007fb3c572f210 ...>>], [BasicObject, #<ActiveRecord::PredicateBuilder::BasicObjectHandler:0x00007fb3c572f1c0 @predicate_builder=#<ActiveRecord::PredicateBuilder:0x00007fb3c572f210 ...>>]]>, @delegate_to_klass=false, @future_result=nil, @records=nil, @async=false, @none=false, @should_eager_load=nil, @arel=nil, @to_sql=nil, @take=nil, @offsets=nil, @cache_keys=nil, @cache_versions=nil>
=> 

My environment

OS: Ubuntsu 20.04.3(WSL)
Ruby version: ruby 3.2.4 (2024-04-23 revision af471c0e01) [x86_64-linux]
Rails version: 7.2.1
active-hash version: 3.3.1

The rails uses sqlite3 as database.
sqlite3 version: 3.37.2 2022-01-06 13:25:41 872ba256cbf61d9290b571c0e6d82a20c224ca3ad82971edc46b29818d5dalt1

@MoAI522
Copy link
Author

MoAI522 commented Sep 21, 2024

I think it occurs by line below:

join_model.send(association_id.to_s.singularize)

join_model is treated without identifying whether it is ActiveRecord or ActiveHash.
But I couldn't find the way to fix it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant