Skip to content
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

Adding conditional callbacks #495

Merged
merged 6 commits into from
Oct 28, 2020
Merged

Adding conditional callbacks #495

merged 6 commits into from
Oct 28, 2020

Conversation

jwoertink
Copy link
Member

Fixes #483

This PR does 2 things.

  • It removes the skip_* macros that I just put in the other day
  • It adds in the ability to conditionally run callbacks

You can read through the issue for more info, but a quick TL;DR: You can still skip callbacks, it's just done by override a method yourself instead of a macro doing it for you.

This allows us to now do things like this:

abstract class SaveTransaction < Transaction::SaveOperation
  before_save :validate_card_number, if: :new_transaction?
  def validate_card_number
    card_number.value == 42
  end
end

class CreateTransaction < SaveTransaction
  permit_columns :card_number, :exp_date
  private def new_transaction?
    true
  end
end

class UpdateTransaction < SaveTransaction
  permit_columns :exp_date
  private def new_transaction?
    false
  end
end

Copy link
Member

@matthewmcgarvey matthewmcgarvey left a comment

Choose a reason for hiding this comment

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

Just missing the error for an invalid unless, otherwise it looks good and I'm glad we can remove those skips.

src/avram/callbacks.cr Show resolved Hide resolved
Copy link
Member

@paulcsmith paulcsmith left a comment

Choose a reason for hiding this comment

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

So stoked for this!

spec/operations/save_operation_callbacks_spec.cr Outdated Show resolved Hide resolved
src/avram/callbacks.cr Outdated Show resolved Hide resolved
src/avram/callbacks.cr Outdated Show resolved Hide resolved
src/avram/callbacks.cr Outdated Show resolved Hide resolved
src/avram/callbacks.cr Outdated Show resolved Hide resolved
src/avram/callbacks.cr Outdated Show resolved Hide resolved
@jwoertink
Copy link
Member Author

/sparkle @matthewmcgarvey for the review

@jwoertink
Copy link
Member Author

jwoertink commented Oct 22, 2020

I'm moving these compile errors to look like this:

Screen Shot 2020-10-22 at 3 27 58 PM

Screen Shot 2020-10-22 at 3 31 46 PM

…oved compile time errors out for a little less clutter
@jwoertink
Copy link
Member Author

weird... no clue why ameba failed randomly... Probably a fluke though.

@jwoertink
Copy link
Member Author

Ok, turns out it's doing this locally as well

Screen Shot 2020-10-22 at 3 59 42 PM

@matthewmcgarvey
Copy link
Member

@jwoertink it seems to be the Callbacks module. Here is the most minimal I'm able to make the file and still cause that error

module Avram::Callbacks
  macro conditional_error_for_inline_callbacks
    \{%
      raise ""
    %}
  end

  macro before_save(if _if = nil)
  end
end

@jwoertink jwoertink changed the title Adding conditional callbacks [DO NOT MERGE] Adding conditional callbacks Oct 23, 2020
@jwoertink
Copy link
Member Author

It seems I've unearthed some ameba bugs... crystal-ameba/ameba#169 😂 oops..

@veelenga
Copy link

veelenga commented Oct 26, 2020

@jwoertink the buggy rule is disabled for a while. I think this work is not blocked anymore by Ameba if you pull the latest master. Thanks for reporting.

@jwoertink
Copy link
Member Author

@veelenga cool, thanks! I was mainly keeping it open so we could reference it and use it for a "test ground" if we needed.

@@ -1,29 +1,77 @@
module Avram::Callbacks
# :nodoc:
macro conditional_error_for_inline_callbacks(callback, method_name, condition)
\{%

Choose a reason for hiding this comment

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

@jwoertink could you please elaborate on why the leading slash is needed here? I think this is causing the compiler to report the incorrect location.

As I can see from the doc it is used to prevent evaluating a macro the outer macro, which is not the case here.

https://crystal-lang.org/reference/syntax_and_semantics/macros.html#nested-macros

Copy link
Member Author

Choose a reason for hiding this comment

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

I have the macro interpolation in this, and without the leading slashes, the compile-time error produces the curly brace literals.

# with the leading slash, I get
You must pass a Symbol to `if`

# without the leading slash, I get
You must pass a Symbol to `{{ condition.id }}`

Copy link
Member

@matthewmcgarvey matthewmcgarvey left a comment

Choose a reason for hiding this comment

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

Woops! didn't realize I was still blocking

@jwoertink jwoertink changed the title [DO NOT MERGE] Adding conditional callbacks Adding conditional callbacks Oct 28, 2020
@jwoertink
Copy link
Member Author

Sweet! Thanks for the update @matthewmcgarvey. Now that it's using Ameba master, it's all passing. Also looks like the crystal issue was fixed in master, so next release of those will be good again 👍

@jwoertink jwoertink merged commit b7a915e into master Oct 28, 2020
@jwoertink jwoertink deleted the issues/483 branch October 28, 2020 19:09
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.

Conditional callbacks
4 participants