-
Notifications
You must be signed in to change notification settings - Fork 898
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
virtual_delegate: make delegation more powerful #10476
Conversation
raise ArgumentError, 'Delegation needs an association. Supply an options hash with a :to key as the last argument (e.g. delegate :hello, to: :greeter).' | ||
end | ||
delegate(*methods, options) |
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.
Seems like we can remove the uses of :allow_nil => true
since we are no longer deferring to delegate
:
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 no longer a valid comment since the new changes.
From your description (as of 2:02 PM CDT, Aug 17th)
I think it is important in the |
|
||
# delegate(method, options) | ||
definition = (method =~ /[^\]]=$/) ? 'arg' : '*args, &block' | ||
default_value = options[:default] ? "|| #{options[:default]}" : 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.
:default
here is going to be a bit tricky...
If you want it to be a static string, you will have to define it as:
virtual_delegate :name, :to => :host, :prefix => true, :default => '"N/A"'
Which is fine, because it allows :default
to be another method, but that is not very obvious to the user/developer this is being done. Is there an easier way to make this more obvious or user friendly? Perhaps use two different keys: :default_value
and :default_method
(:default_value
would do an .inspect
on the value)?
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.
I like inspect. don't want a method
very good find - thanks
I think the code changes here are fine aside from the few things that I brought up. Shouldn't cause any regressions as far as I can tell, and if so, they would show up in I do have a few follow up questions though:
|
5dadb68
to
eadd79f
Compare
@@ -66,43 +66,99 @@ module ClassMethods | |||
# | |||
|
|||
def virtual_delegate(*methods) | |||
options = methods.pop | |||
unless options.kind_of?(Hash) && options[:to] | |||
options = methods.extract_options! || {} |
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.
extract_options! is designed to always give you a hash, so the || {}
is not needed.
[1] pry(main)> require 'active_support/all'
=> true
[2] pry(main)> [].extract_options!
=> {}
[3] pry(main)> [{:a => 1}].extract_options!
=> {:a=>1}
[4] pry(main)> [:foo, {:a => 1}].extract_options!
=> {:a=>1}
@kbrock I like the signature...very clear.
Can you show this example in the after case? I assume it returns 0 because a default was specified. What happens if no default is specified. |
end | ||
|
||
location = caller_locations(1, 1).first | ||
file, line = location.path, location.lineno |
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.
These two lines are here only to be used by the define_delgate
method. Would it be possible to just call these within the define_delgate
method itself? You might have/want to update the first line if you want to provide an accurate location for errors, because you would now be farther down the stack:
location = caller_locations(2,1).first
https://ruby-doc.org/core-2.1.0/Module.html#method-i-module_eval
https://ruby-doc.org/core-2.1.0/Kernel.html#method-i-caller_locations
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.
@NickLaMuro I didn't have much success with caller_locations(2,1).first
, but I'll try again. it sure would make it easier to read and closer to delegate
<pr_mergeability_checker />This pull request is not mergeable. Please rebase and repush. |
5775272
to
46ee25c
Compare
fixed line number, and multiple "." detection, and extracted virtual_attribtue work and all other comments I could do |
89910ce
to
aef8c7c
Compare
LGTM 👍 -- @Fryguy any concerns before merging? |
<pr_mergeability_checker />This pull request is not mergeable. Please rebase and repush. |
since it is called from within a block, it uses 3 instead of the expected 2
this syntax is easier to read
aef8c7c
to
6e4a129
Compare
Checked commits kbrock/manageiq@7ca5654~...6e4a129 with ruby 2.2.5, rubocop 0.37.2, and haml-lint 0.16.1 lib/extensions/ar_virtual.rb
|
I'm not thrilled with the copying of the define_delegate method, but I can't think of another way to do it, so will merge. |
@Fryguy we will find a way to get rid of the delegate copy. |
BLOCKED by:
virtual_attribute
portion)background
We liberally use
virtual_attribute
in our model definitions.The
:arel
option allows us to define SQL that will use the attributes within queries.This arel option is very important. It allows screens to only download 20 records for the screen rather than having to download every record and pruning in ruby.
The SQL used by
:arel
is tricky to construct, so helper methods likevirtual_delegate
automatically generate it.This PR adds 2 enhancements to
virtual_delegate
by duplicating and modifyingActiveSupport
's owndelegate
method::to
to specify a name and description (e.g.::to => "hardware.cpu_sockets"
):default
option, sonil
references return something other thannil
.before
The method
Vm#num_cpu
is defined as an attribute with ruby method definition.Pages that sort by
num_cpu
bring back everyVm
and correspondingHardware
records into memory. Then 20 of those records are picked and displayed on the screen.after
virtual_delegate
Defines the attribute with a sql component and the delegate ruby method:
Issues:
We wanted
num_cpu
to callhardware.cpu_sockets
.after improving
:to
optionDefines the attribute with a component and the delegate ruby method:
Good:
It will also define a
virtual_attribute
witharel
properly so it is valid in SQL:These generate the following SQL:
Issue:
We want
num_cpu
to default to0
.after adding
:default
optionDefines the attribute with a component and the delegate ruby method:
Good:
The code works as it did before, only now, on the vms page, are able to sort by
num_cpu
s - so it goes from 49s to 12s (10k vms)