Skip to content

change from present? (Rails) to native Ruby check #57

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

Merged
merged 4 commits into from
Sep 17, 2024

Conversation

mculp
Copy link
Contributor

@mculp mculp commented Sep 10, 2024

I'm not sure where present? (a method defined in Rails) is being pulled in from, but for me, it's not:

NoMethodError: undefined method `present?' for nil (NoMethodError)

        elsif multi_tenant.present?
                          ^^^^^^^^^

I wonder if a truthiness check is good enough: elsif multi_tenant

or do we need to explicitly check that it's not empty, similar to present?

I'm not sure where `present?` (a method defined in Rails) is being pulled in from, but for me, it's not:

```sh
NoMethodError: undefined method `present?' for nil (NoMethodError)

        elsif multi_tenant.present?
                          ^^^^^^^^^
```

I wonder if `elsif multi_tenant` is good enough, or do we need to explicitly check that if it has an `empty?` method, that the `empty?` method returns false (similar to what `present?` does)
@mculp mculp changed the title change from present? to ruby-only check change from present? (Rails) to native Ruby check Sep 10, 2024
@@ -45,7 +45,7 @@ def create(
req.body["properties"] = properties unless properties.nil?
if multi_tenant.is_a?(Hash)
req.body["multiTenancyConfig"] = multi_tenant
elsif multi_tenant.present?
elsif multi_tenant && !(multi_tenant.respond_to?(:empty?) && multi_tenant.empty?)
Copy link
Collaborator

@andreibondarev andreibondarev Sep 10, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mculp If you look at the method signature: multi_tenant: nil, so it's either nil or "whatever the user passes in" (which should be true.

Copy link
Collaborator

@andreibondarev andreibondarev Sep 10, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wondering if we should just change the method signature to:

def create(
  multi_tenant: false

and then in the method itself, always set the multiTenancyConfig to:

req.body["multiTenancyConfig"] = {enabled: multi_tenant}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like this code is allowing a Hash to be passed in and set instead of { enabled: true }

if multi_tenant.is_a?(Hash)
  req.body["multiTenancyConfig"] = multi_tenant

I think because this is valid, according to the docs:

    multi_tenancy_config=Configure.multi_tenancy(
        enabled=True,
        auto_tenant_creation=True
    )

so looks like there are two options here we need to handle

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wdyt about:

def create(
  multi_tenant: false,
  auto_tenant_creation: false,

# ...

req.body["multiTenancyConfig"] = { enabled: multi_tenant }
req.body["multiTenancyConfig"].merge!(auto_tenant_creation: auto_tenant_creation) if auto_tenant_creation

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mculp I don't see the auto_tenant_creation option. I'm not sure what the Python client implement but this gem just interfaces with the REST API.

https://weaviate.io/developers/weaviate/config-refs/schema

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, if you'd like to change it -- let's do it!

Copy link
Contributor Author

@mculp mculp Sep 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made a couple real HTTP calls from the client and checked that this did automatically create tenants when set up properly. I think it'd be nice to use something like VCR for recording requests and responses for use in tests. I started to set it up in this PR, but decided to limit the changeset here as much as I could.

I left the is_a?(Hash) check in there for backwards compatibility. It seems like whoever added this is using the code like:

schema.create({
  class_name: "Question",
  multi_tenant: { enabled: true, autoTenantCreation: true, autoTenantActivation: true }
})

I added a shortcut:

schema.create({
  class_name: "Question",
  multi_tenant: true,
  auto_tenant_creation: true,
  auto_tenant_activation: true
})

These result in the same multiTenancyConfig, and I added a spec for the new case.

It seems a little less than optimal, but I didn't want scope to creep too far. I'm mainly here about the .present? issue.

That said, while I was testing, I found one more instance of .blank? (another Rails method, the inverse of .present?) and just changed it to .nil? (Ruby method).

While I was writing this code, I had a lot of ideas for refactoring/simplification, but wanted to go ahead and ship this before moving on to anything else.

Comment on lines +81 to +90
before do
@captured_request = nil
allow_any_instance_of(Faraday::Connection).to receive(:post) do |_, path, &block|
expect(path).to eq("schema")
req = OpenStruct.new(body: {})
block.call(req)
@captured_request = req
response
end
end
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VCR or WebMock would simplify this a ton, but this is essentially grabbing the req object yielded to Faraday so we can check that multiTenancyConfig is set up correctly.

@mculp
Copy link
Contributor Author

mculp commented Sep 13, 2024

whoops, I’ll fix the rubocop issues tonight

@@ -27,6 +27,8 @@ def create(
description: nil,
properties: nil,
multi_tenant: nil,
auto_tenant_creation: nil,
auto_tenant_activation: nil,
Copy link
Collaborator

@andreibondarev andreibondarev Sep 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like it would be simpler to just default to false as that's what Weaviate itself does:

def create(
    ...
    multi_tenant: false,
    auto_tenant_creation: false,
    auto_tenant_activation: false

And we'd just always set those values:

req.body["multiTenancyConfig"] = {enabled: multi_tenant, autoTenantCreation: auto_tenant_creation, autoTenantActivation: auto_tenant_activation}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking that it was strange that multi_tenant was the only arg that didn't match the weaviate arg, but didn't want to make a whole lot of changes in this PR.

MultiTenancyConfig = Struct.new(:enabled, :autoTenantCreation, :autoTenantActivation) do
  def initialize(enabled: false, autoTenantCreation: false, autoTenantActivation: false)
    super
  end
end
create(
  ... 
  multi_tenancy_config: MultiTenancyConfig.new
)

Since this can be used in update as well, I think it'd make sense to have a small Struct that defines the options.

For now, I'll go with your suggestion, because we are way off track of fixing the present? / blank? issue

Copy link
Contributor Author

@mculp mculp Sep 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, just to be sure, you want me to blow away the existing code for this? I was trying to keep it backwards compatible.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, please!

I think it's okay, I'll release a 0.10 to signify the breaking change here.

@andreibondarev andreibondarev merged commit 45f48c9 into patterns-ai-core:main Sep 17, 2024
6 checks passed
@andreibondarev
Copy link
Collaborator

Great job, thank you!

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

Successfully merging this pull request may close these issues.

2 participants