-
Notifications
You must be signed in to change notification settings - Fork 900
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
[WIP] add hosts and vms as an association #12884
[WIP] add hosts and vms as an association #12884
Conversation
@chrisarcand do you have any idea how to handle this error?
This is because I want to model the relation basically like this class NetworkManager
belongs_to :parent_manager, :class => 'ExtManagementSystem'
has_many :hosts, :through => :parent_manager
end
class ExtManagementSystem
has_many :hosts
end |
@durandom Something must be expecting that you can modify vms and hosts on NetworkManagers, which you can do with the delegation and not a What's the stack trace on that error? Can you find the places where modification is happening and just avoid it? If so, callers can be updated and you can make this change. Else, you won't be able to do it exactly this way and will have to make methods that return empty relations in the absence of a parent manager (icky...it'll make things work as normal before but that's pretty hacky) Vague help I know; I need more direct experience with all these provider manager entities so I can be of more specific help. |
@durandom hm, weird thing is that this fails during @ems.destroy could be it is trying to call e.g. the nullify defined on ems like: has_many :hosts, :foreign_key => "ems_id", :dependent => :nullify, :inverse_of => :ext_management_system could you check the details of the NetworkManager hosts? It has some settings from the base class? |
By redefining it on the NetworkManager it has only the options that are added there. @chrisarcand can I make the association somehow readonly? I also came up with adding methods like def hosts
network_manager ? network_manger.hosts : []
end But that seems not as elegant as using a proper association. |
@durandom adding method, that is basically delegation (but delegation doesn't support default value when it's nil) Also the default value would need to be Arel, not just []. We can still have calls hosts.where(xy) But ^ seems to me like a bug in Rails really. It should not call the destroy on hosts, when you've overwritten the relation and it doesn't have a cascade delete. |
absolutely. But for lack of knowledge I just took the short path. |
Here is a nice self contained test that @chrisarcand came up with. Until then, dont know, go with the method solution. begin
require "bundler/inline"
rescue LoadError => e
$stderr.puts "Bundler version 1.10 or later is required. Please update your Bundler"
raise e
end
gemfile(true) do
source "https://rubygems.org"
# Activate the gem you are reporting the issue against.
gem "activerecord", "5.0.0.1"
# gem "activerecord", "4.2.7.1"
gem "sqlite3"
end
require "active_record"
require "minitest/autorun"
require "logger"
# Ensure backward compatibility with Minitest 4
Minitest::Test = MiniTest::Unit::TestCase unless defined?(Minitest::Test)
# 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 "hosts", force: :cascade do |t|
t.integer "manager_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["manager_id"], name: "index_hosts_on_manager_id"
end
create_table "managers", force: :cascade do |t|
t.integer "manager_id"
t.string "type"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["manager_id"], name: "index_managers_on_manager_id"
end
end
class Host < ActiveRecord::Base
belongs_to :manager
end
class Manager < ActiveRecord::Base
has_one :network_manager, :dependent => :destroy
has_many :hosts, :dependent => :nullify
end
class NetworkManager < Manager
belongs_to :manager
has_many :hosts, :through => :manager
end
class BugTest < Minitest::Test
def test_association_stuff
manager = Manager.create
network_manager = NetworkManager.create
network_manager.manager = manager
network_manager.save
assert manager.destroy
end
end |
@durandom I don't have the Nuage manager currently, but from how it looks, the issue will be there so for now, should we go with: def hosts
parent_manager ? parent_manager.hosts : Host.none
end ? |
hm, I was fairly sure this will fix https://bugzilla.redhat.com/show_bug.cgi?id=1383307 but seems like the through relation here is not really a through relation, but it does delegate instead? At least I don't see any join to parent_manager, I would expect here, but it directly uses the parent_manager id in the query. @kbrock @chrisarcand ^ and that could be a reason why this fails on destroy, since this is not a proper has_many |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is great marcel
just the spec change and I'll merge
# require .hosts and .vms to return a relation | ||
# https://bugzilla.redhat.com/show_bug.cgi?id=1393675 | ||
manager = FactoryGirl.build(:ems_network) | ||
expect(manager.hosts).not_to be_nil |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could you test that this is a relation instead of not_nil
?
We are using all of these:
expect(manager.hosts).to be_a_kind_of(ActiveRecord::Relation)
expect(manager.hosts).to be_kind_of(ActiveRecord::Relation)
expect(manager.hosts).to be_a(ActiveRecord::Relation)
some methods in ExtManagementSystem expect these to return an association and as we can have NetworkManagers without a parent_manager we must not delegate those methods
40e86d7
to
3a86a9d
Compare
Checked commit durandom@3a86a9d with ruby 2.2.6, rubocop 0.47.1, and haml-lint 0.20.0 |
Yeah, unfortunately azure still fails. I'll add this very test here as well.
|
@miq-bot add_label wip |
Really dislike overriding these models in subclasses. Having said that, can we keep as an association, just link via the parent_manager_id ? class NetworkManager
has_many :hosts, :foreign_key => 'parent_manager_id'
end If we have to use a virtual association, lets default to |
I'm gonna try to fix all of these using #14978 and #12884 (comment) |
This pull request has been automatically closed because it has not been updated for at least 6 months. Feel free to reopen this pull request if these changes are still valid. Thank you for all your contributions! |
some methods in ExtManagementSystem expect these to return an
association and as we can have NetworkManagers without a parent_manager (e.g. Nuage)
we must not delegate those methods
Links
@miq-bot add_labels bug, euwe/yes
@miq-bot assign Ladas
@Ladas please review