I have a table with a couple of boolean columns.
A PurchaseOrder needs to be marked as complete (first boolean), before it is invoiced (the second boolean).
I'd appreciate some pointers as to how to validate legal combinations of these booleans.
What I have in mind is something like,
:validates (!:complete and !:invoiced) or (:complete && :invoiced) or (:complete && !:invoiced)
Is this possible?
Use a custom validator
Sounds like your PurchaseOrder goes through several states during its life cycle, like a finite-state machine.
One thing we use in production systems is acts_as_state_machine, to help accomplish this behavior.
It allows you to define:
a series of states that an object can be in
the events that move the object between states
and finally which states you can move between, and which states you can't move between. For example, you might want to allow your PurchaseOrder to be go from complete->to->invoiced, but not backwards from invoiced->to->complete. acts_as_state_machine allows you to set this up in a declarative style.
acts_as_state_machine will allow you to define those complex behaviors. Reading it takes a bit of time to understand it, but for systems like these, it has been a life saver.
Related
Currently we are using graphql/graphql-ruby library. I have wrote few queries and mutations as per our requirement.
I have the below use case, where i am not sure how to implement it,
I have already an query/endpoint named allManagers which return all manager details.
Today i have got requirement to implement another query to return all the managers based on the region filter.
I have 2 options to handle this scenario.
Create an optional argument for region , and inside the query i need to check if the region is passed then filter based on region.
Use something like https://www.howtographql.com/graphql-ruby/7-filtering/ .
Which approach is the correct one ?
Looks like you can accomplish this with either approach. #2 looks a bit more complicated, but maybe is more extensible if you end up adding a ton of different types of filters?
are you going to be asked to select multiple regions? or negative regions (any region except north america?) - those are the types of questions you want to be thinking about when choosing an approach.
Sounds like a good conversation to have with a coworker :)
I'd probably opt to start with a simple approach and then change it out for a more complex one when the simple solution isn't solving all of my needs any more.
I am looking for a data structure or design pattern to work with rails and active record to provide a way to make configurable events and event triggers based on real time events.
While this is not the end usage for this sort of system, the follow example I believe demonstrates what I am trying to do. Similar to an log monitoring system like splunk, essentially what I am trying to do is create a system where I can take some attribute from an object and then compare it to a desired value and take perform an action if the evaluation is true.
Is there a library to do this or would something need to be rolled out from scratch. The way I was thinking about designing this would be similar to the following:
I would have an Actor (not in the traditional concurrency sense) which would house the attributes that I want to compare to. Then I would have a Trigger model which would have a pointer to the actor_id, attribute (IE count), comparator (<, <=, ==, >=, >), value, and action_id. The action_id would point to an object with a perform method that would just house the code that needs to run when the trigger is fired.
So in the end the trigger would evaluate to something like:
action.perform if actor.send(attribute) comparator value
Another option, possibly a more standard one, seems to develope a DSL (IE FQL for facebook). Would this be a better and more flexible approach.
Is this something that a library can handle or if not is this a decent structure for a system like the one I am proposing?
EDIT: Looks like a DSL might be the most flexible way to go. Tutorials for writing DSL in Ruby
If I understand the question correctly, what you have written is nearly correct as it stands. You can send comparison operators as symbols, like so:
comparator = :>
action.perform if actor.send(attribute).send(comparator, value)
# action will perform if actor's attribute is greater than value
If two scenarios can occur at the same time, does that (always/ever) constitute a third scenario?
My current thinking is that they are not necessarily exclusive (depends on the scenario). If you have two scenarios that could occur at the same time that they would only require a third scenario if the Given/When/Then steps do not merge implicitly or if one scenario takes precedence over the other.
This question has arisen whilst thinking about scenarios for what is essentially a form of injection in which Collections of objects get injected into another object ( https://github.com/jameskennard/mockito-collections ). So given the two scenarios "Class of object under test has a List of collaborators" and "Class of object under test has a Set of collaborators". Both could occur at the same time so a third scenario could be "Class of object under test has a List and a Set of collaborators". But it doesn't feel right, it's just too verbose, I think the Given/When/Then steps would be seen to merge implicitly. (Have a bad feeling I may have just answered my own question)
Anyone have any differing thoughts?
I think the key here is the behavior. The potential third scenario ("Class of object under test has a List and a Set of collaborators") that you're asking about is of course real but the behavior is already covered by the other two scenarios so I'd say there is no need to write another scenario.
If the combination of givens was to result in different behavior there would certainly be a third scenario but I believe the two you have cover the behavior you're looking to define.
At the moment, your sentences above are describing state rather than behavior.
What is the different outcome you get in each of the different contexts? I would expect something like this:
Given my CUT has five collaborators
When I do my thing with the class
Then it should use each collaborator in turn.
Given my CUT has five collaborators
And the fourth and fifth collaborators are identical
When I do my thing with the class
Then it should only use the fourth collaborator once.
That would illustrate the different behavior of the list (ordered) and the set (no duplicates).
If those two elements are truly beneficial independently, then yes, they're two separate scenarios. If they both have to be present for the class to have any value, I'd merge them into one:
Given my CUT has five collaborators
And the fourth and fifth collaborators are identical
When I do my thing with the class
Then it should use each collaborator in turn
And it should only use the fourth collaborator once.
An example of two simultaneous benefits might be getting cash out of an ATM, in which the cash is delivered and the account is also debited. You couldn't do either of those independently. Offering a receipt for the transaction would be a separate benefit, as it doesn't need to occur for an ATM to be of value. Hope this helps to make the distinction.
I want to perform some simple calculations while staying database-agnostic in my rails app.
I have three models:
.---------------. .--------------. .---------------.
| ImpactSummary |<------| ImpactReport |<----------| ImpactAuction |
`---------------'1 *`--------------'1 *`---------------'
Basicly:
ImpactAuction holds data about... auctions (prices, quantities and such).
ImpactReport holds monthly reports that have many auctions as well as other attributes ; it also shows some calculation results based on the auctions.
ImpactSummary holds a collection of reports as well as some information about a specific year, and also shows calculation results based on the two other models.
What i intend to do is to store the results of these really simple calculations (just means, sums, and the like) in the relevant tables, so that reading these would be fast, and in a way that i can easilly perform queries on the calculation results.
is it good practice to store calculation results ? I'm pretty sure that's not a very good thing, but is it acceptable ?
is it useful, or should i not bother and perform the calculations on-the-fly?
if it is good practice and useful, what's the better way to achieve what i want ?
Thats the tricky part.At first, i implemented a simple chain of callbacks that would update the calculation fields of the parent model upon save (that is, when an auction is created or updated, it marks some_attribute_will_change! on its report and saves it, which triggers its own callbacks, and so on).
This approach fits well when creating / updating a single record, but if i want to work on several records, it will trigger the calculations on the whole chain for each record... So i suddenly find myself forced to put a condition on the callbacks... depending on if i have one or many records, which i can't figure out how (using a class method that could be called on a relation? using an instance attribute #skip_calculations on each record? just using an outdated field to mark the parent records for later calculation ?).
Any advice is welcome.
Bonus question: Would it be considered DB agnostic if i implement this with DB views ?
As usual, it depends. If you can perform the calculations in the database, either using a view or using #find_by_sql, I would do so. You'll save yourself a lot of trouble: you have to keep your summaries up to date when you change values. You've already met the problem when updating multiple rows. Having a view, or a query that implements the view stored as text in ImpactReport, will allow you to always have fresh data.
The answer? Benchmark, benchmark, benchmark ;)
I'm working on a RoR app, but this is a general question of strategy for OOP. Consider the case where there are multiple types of references that you are storing data for: Books, Articles, Presentations, Book Chapters, etc. Each type of reference is part of a hierarchy where common behaviors sit at the most general point of inheritance, and at the DB level I am using single-table inheritance. The type is set by use of a select option, so lets say that I was entering the data as if it were a Book, but then realize that it is only a chapter. So I change the type of reference by selecting "Book Chapter", which then posts an update to the existing model/form. The question is what is the correct strategy for handling this?
On one hand it seems preferable to transform the existing record in the DB to avoid id exhaustion, and potentially save on operations for creating/deleting records. This however tends to make the update strategy complex.
On the other hand, it seems more in keeping with general object orientation to create a new object (and record) using the old object to initialize values that you want to persist, then delete the old object. This I think makes more sense in terms of an Object Space (heap), and I think is more aligned to ideas like those of general systems.
However, I haven't nailed this down, and after sitting on it for a while, I'm pitching it to this community to see what "right" way to do this is.
Prefer immutable objects, in other words: the second strategy. Your objects may not be immutable by themselves, but reducing mutability is often a step in the right direction.
Besides that, this is the more natural way. In general OOP terms there's no way to change the type of an object. In your situation you can, but it's still an awkward and unusual thing to do.
On the other hand, if your objects are represented by the same (identical) class and changing the type is done by setting a high-level property, one could argue that re-creating the object is overkill.
Still, reducing mutability is a good think, but if your class is already designed to be mutable, it might not be worth it. (In that special case where there's actually only one actual class from the language point of view)
The transformation you're talking about doesn't seem to warrant a new record or even a new object.
Each of the entries you cited have the same form. They are block of text with siblings, parents and children. A chapter may have a block of text, with a parent book and a child endnote, for example. They are differentiated on a DB level only by their type, which itself could be a field.
All you need is a model to handle these 'elements' differently depending on whether or not it is flagged as a book, or a chapter, etc. If an element is flagged as a chapter, yet has no parent, for example, then you might flag it as a 'book' when it is saved to the DB.
Changing the way an element is flagged doesn't change the element, it only changes the way it is viewed. So long as the element knows how to find it's children the data will compute in the same way. As far as the model is concerned it's just an element you're worrying about. The rest is done in the UI.