-
-
Notifications
You must be signed in to change notification settings - Fork 152
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
Introducing Hanami::Repository#query #342
Conversation
repository = OperatorRepository.new | ||
operator = repository.create(s_name: 'F') | ||
|
||
records = repository.query.where(s_name: 'F').to_a |
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.
use q
instead query
?
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.
You're right, thank you!
all perfect @jodosha it makes sense that change. could you take a look that comment? |
936ed3d
to
2c0fbd2
Compare
Why add an alias? Having a |
@pascalbetz I consider it a handy shortcut for Hanami console. WDYT? |
What about using relations from a repo directly? They simply return data back as structs so should be enough for tests and console |
@solnic Do you mean to avoid |
I think this is dangerous as it will certainly be abused. I definitely understand the benefits in the console but as far as tests are concerned, I think one should not test stuff that is not exposed via a clean API (in that case, is it really relevant that the draft lives in the database?). |
Yes, I understand the risk.
This isn't always true. Again in my projects half of methods in repositories were defined because of testing purposes. This is especially true for complex commands that create multiple records at once.
How can we solve this problem? |
@jodosha i prefer unique names for things, if I could i would get rid of aliases in ruby ( Other solutions: You can of course rename the method from But more seriously: repo.send(:query)
// or even shorter, i would not mind the alias if it is not in the public API
repo.send(:q) to access the query...this would clearly say "this is private API, do not use". |
What about naming the method |
This requires more discussion, I'd keep out from 0.7.0 milestone. |
@jodosha how about having a method on Hanami::Model.enable_test_mode! I see that you already have descendant tracking via |
if one needs to write methods just for test purposes, this probably could mean either:
In case, described in description of this PR it is not clear (personally to me) why not RSpec.describe ArticleRepository do
it "creates draft articles" do
repository = described_class.new
draft = repository.create_draft(title: "Introducing Hanami")
drafts = repository.drafts
expect(drafts).to include(draft)
end
end (following original style of test-case) And btw, it seems (to me), if one needs query interface as public, than why choose repository-pattern based solution instead of active record or smth. like that? |
A little late to the party, most of what I'd say has already been said, so to make it really short:
|
@TiteiKo I like your approach. How would you implement the first two points? |
@jodosha You could have your |
Either expose it or not. If it is exposed, then it's public API and people will and should use it. If you need to go such great lengths to expose something but only in the console/development then this is an indicator that the API is flawed. |
@pascalbetz I disagree – the console should be used mainly for debugging purposes, and thus should come equipped with all possible tools to inspect data, but those tools should not be available from within the application. |
@beauby my 5 cents: myobject.send(:something_that_you_do_not_want_to_expose).do_something_you_should_not_do_on_production problem solved. A bit longer but hardly a problem. No explanation required why you have a method but should not use it. |
@pascalbetz I agree – I was more thinking of a method that would be added to |
Have some candy. But don't eat it. Will go wrong:-) |
@beauby What about testing code? What's your opinion on that? |
@pascalbetz In other words, do you want to introduce |
@jodosha My opinion on testing is that one should not test stuff that is not exposed, because one should test behavior rather than implementation. I may be missing the point, but I'd like to see a situation where using |
Just like in case of #351 issue - you can use relations, they are the interface for talking to a database, and they are public in repositories. It is up to you where you're OK with having them leak into your app or test code. Also, if you don't like to use "raw" data in the form of rom structs, you can always do |
@jodosha not necessarily. I just don't like to have a public interface that is not really public (only console...). If you need to get access to the internals for debugging/testing/playing around you can do so with |
This seems to be controversial, until we find a good solution, I'm closing this. 😄 |
The Problem
Until
hanami-model
0.6, all the queries are private.This was a strong guidance for developers to write intention revealing methods in repositories instead of leaking storage abstractions all over the code base.
It avoided code like
ArticleRepository.where(state: 'draft')
to be used directly in actions code.Developers were forced to write a meaningful method
ArticleRepository.drafts
to get access to the data they were interested into.This has the huge downside of being not convenient for testing code and Hanami console.
I found myself to define over and over methods in repositories only for testing purposes.
As the time passed, half of the methods defined in repositories were defined because of testing purposes (like
#drafts_by_title
) in the example above.The Solution
This PR introduces
Repository#query
(aliased as#q
) to allow developers to directly access the database relation and build inline queries.The documentation warns developers to use inline queries only for testing purposes and Hanami console.
Let's rewrite the testing code above:
We don't need to define
#drafts_by_title
in that repository anymore./cc @hanami/core-team @hanami/contributors @solnic @flash-gordon