GithubHelp home page GithubHelp logo

Comments (4)

nvasilevski avatar nvasilevski commented on June 16, 2024 1

@Jay0921 While this should work as well, overriding primary_key is less preferable just because I find it semantically incorrect. I treat primary_key as a term coming from the db-level and I would prefer it to reflect the actual state of the database schema. This is why query_constraints is a little better option since it will behave as a "virtual primary key" while not making primary_key value misleading.

But ultimately I agree that there is a legit issue (limitation) in current Rails capabilities and it needs to be addressed

from rails.

nvasilevski avatar nvasilevski commented on June 16, 2024

Hey, I created a reproduction script (with a potential fix included) so we can be sure we are discussing the same model setup:

# frozen_string_literal: true

require "bundler/inline"

gemfile(true) do
  source "https://rubygems.org"

  git_source(:github) { |repo| "https://github.com/#{repo}.git" }

  gem "rails"
  # If you want to test against edge Rails replace the previous line with this:
  # gem "rails", github: "rails/rails", branch: "main"

  gem "sqlite3"
end

require "active_record"
require "minitest/autorun"
require "logger"

# This connection will do for database-independent bug reports.
ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
ActiveRecord::Base.logger = Logger.new(STDOUT)

ActiveRecord::Schema.define do
  create_table :tickers, id: false, force: true do |t|
    t.integer :gvkey
    t.primary_key :iid
  end

  create_table :co_actions, id: false, force: true do |t|
    t.integer :gvkey
    t.primary_key :iid
  end
end

class Ticker < ActiveRecord::Base
  query_constraints :gvkey, :iid
end

class CoAction < ActiveRecord::Base
  belongs_to :ticker, query_constraints: [:gvkey, :iid]
end

class BugTest < Minitest::Test
  def test_association_stuff
    ticker = Ticker.create!(gvkey: 123)
    CoAction.create!(gvkey: 123, iid: ticker.iid)
    assert_equal ticker, CoAction.take.ticker
  end
end

While I think your situation may be considered as a limitation in Rails I just wanted to share that there is a high chance that by defining query_constraints :gvkey, :iid on the Ticker model you'll get the behavior you are looking for.
It will lead to the Ticker objects to be always referenced by two columns and models that belongs_to :ticker may need to explicitly set primary_key: :iid if they want to reference it by just one column but overall this should be a working solution to at least get you unblocked

from rails.

bguban avatar bguban commented on June 16, 2024

Hey @nvasilevski. Thanks for the quick response. I think the problem is conceptual. With the singular primary/foreign keys I was able to specify both (primary and foreign) in the relation and override the primary_key defined in the class but now, with the composite primary key, I'm only able to specify the foreign_key in the relation but the primary key is always taken from the class.

Going back to the schema. The ticker model has its own singular primary key and it connects to other models (except co_action) using its own key. Here is the schema:

ActiveRecord::Schema.define do
  create_table :tickers, id: true, force: true do |t|
    t.integer :gvkey
    t.integer :iid
  end

  create_table :co_actions, id: true, force: true do |t|
    t.integer :gvkey
    t.integer :iid
  end
end

class Ticker < ActiveRecord::Base
  has_many :co_actions, primary_key: [:gvkey, :iid], foreign_key: [:gvkey, :iid]
end

class CoAction < ActiveRecord::Base
  belongs_to :ticker, query_constraints: [:gvkey, :iid], primary_key: [:gvkey, :iid]
end

class BugTest < Minitest::Test
  def test_association_stuff
    ticker = Ticker.create!(gvkey: 123, iid: 321)
    CoAction.create!(gvkey: 123, iid: 321)
    assert_equal ticker, CoAction.take.ticker
  end
end

I understand that the schema looks weird but the co_actions table is given by a 3rd party provider so I can't add a ticker_id column to it.

BTW I was able to patch it. I just override the relation's @association_primary_key right after adding the relation:

class CoAction < ActiveRecord::Base
  belongs_to :ticker, query_constraints: [:gvkey, :iid], primary_key: [:gvkey, :iid]
  reflections['ticker'].instance_variable_set(:@association_primary_key, ['gvkey', 'iid'])
end

from rails.

Jay0921 avatar Jay0921 commented on June 16, 2024

@bguban I'm not sure if this will resolve the problem.

class Ticker < ActiveRecord::Base
  self.primary_key = [:gvkey, :iid]

  has_many :co_actions, query_constraints: [:gvkey, :iid]
end

class CoAction < ActiveRecord::Base
  self.primary_key = [:gvkey, :iid]

  belongs_to :ticker, query_constraints: [:gvkey, :iid]
end

from rails.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.