Comments (4)
I'm definitely open to more options/injectables around persistence. That said, I'm not sure I agree with that abstraction - I like the premise of an OrderResource
persists an Order
, an AddressResource
persists an Address
, and a CompoundOrderResource
is persisted by a CompoundOrderService
that coordinates multiple resources. Cross-pollinating these sounds like we'd end up with some confusing "who does what where" issues, and some "unexpected side-effect" issues similar to what you've seen before with callbacks.
I do think there is probably something to the idea of a JsonapiCompliable::CompoundResource
concept, but I'd like to hear more about these scenarios and problems with the existing paradigm before digging too deep. Maybe you could start down the CompoundOrderResource
route and let me know any problems you run into?
from graphiti.
Hi Derek - great question. I think I have an answer for you, the documentation just hasn't caught up yet. In your example, you could do something like this:
class AddressResource < JsonapiCompliable::Resource
# ... code ...
def create(attributes, parent) # note the optional second arg here
address = Address.new(attributes)
if parent.is_a?(Order)
address.geocode
.time_in_new_timezone(parent.some_time, address.timezone)
end
address.save
address
end
end
Note the check on parent
here - since multiple objects could (in theory) sidepost an address, we should verify it's an Order
doing the sideposting.
Another option would be the after_save
hooks within the parent. I haven't written a how-to yet, but you can see examples in the tests. One way:
# OrderResource
belongs_to :address,
foreign_key: :order_id,
scope: -> { Address.all },
resource: AddressResource do
after_save only: [:create, update] do |order, addresses|
# addresses is always an array regardless of has-many/belongs-to
address = addresses.first
address.geocode(order.some_time, address.timezone)
address.save
end
For both of these examples, you'll already be within a transaction. Make sure to define #transaction
in your adapter if not using activerecord.
Does either of those work for you?
from graphiti.
And by the way, as you noted earlier - another option is to simply post a CompoundOrder
object, rather than sideposting the address. In this case you'd have a CompoundOrder
resource and the attributes
could be whatever structure you want, and you could do whatever you want within the relevant resource methods. I think this is less than ideal, but it's what a lot of RESTful folks did/do before jsonapi introduced sideposting, so no worse than the status quo as a last resort.
from graphiti.
Thanks for the quick reply! Having access to the parent is definitely helpful. I want to avoid callbacks as much as possible; it's gotten us into a lot of trouble in our past API.
I am thinking at this point the compound object would be best. Ideally, I'd like to define a central place where things are happening to an order, so it's easy to see what effects are taking place.
Another option, for future consideration, might be the ability to specify which resource handles the create/update for a relationship. Something like:
# app/resources/order_resource.rb
class OrderResource < ApplicationResource
type :orders
model Order
has_one :address,
resource: AddressResource,
persisted_by: :self, # something to specify OrderResource is handling address params
scope: -> { Address.all },
foreign_key: :address_id
end
This way, AddressResource
can operate as normal in any situation and not know about the custom requirements for OrderResource
, while OrderResource
is smart enough to handle address params in a certain way. What do you think?
from graphiti.
Related Issues (20)
- Inherited resources not rendering parent's attributes (w/ Null Adapter and polymorphism)
- Is it possible to get a list of all Resource class names? HOT 9
- Graphiti::Errors::InvalidLink HOT 1
- Sideposts fail when associating has_many resource with the `as:` option
- Filtering / Sorting a Parent Resource based off its associations value HOT 1
- Ruby-3.0 splits named and positional parameters
- sideposting - associating same newly created record with multiple records that are also being created
- Sideposting- includes don't show when test with Postman
- Polymorphic has_one and has_many doesn't respect custom polymorphic_name
- Data access questions HOT 1
- Missing next page link when the resource is a postgres table has json columns HOT 1
- Proposal to allow for overriding relationship getter HOT 1
- Record ID for authorization
- Guide - Outdated external link
- can not call method with args including keyword inside attribute/extra_attribute
- Problem in namespacing controllers HOT 2
- Template for tutorials are broken
- Parsing filter values with {{}} has unwanted side effects.
- Resources with circular relationships fail to load
- Can not call method with key args inside extra_attribute/attribute block HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from graphiti.