-
Notifications
You must be signed in to change notification settings - Fork 8
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
Feature request: Option for ignoring client-side ids #48
Comments
Hi! Thanks for reaching out. First of all I'm supper happy to hear there are people using custom handlers :) I must say I need some clarification on the issue you're having. It took me a while, but this is my current understanding. If my understanding is correct, this seems like an interesting use case that was probably not tested before. I think in this case it would be super cool if you could provide payload examples. Let me know if I got it right and we can start thinking on how to resolve that issue :) |
Thanks for getting back to me, @Marahin. Yes, you seem to have it correct. Please see below example of use-case: class Post < ApplicationRecord
has_many :quotations
accepts_nested_attributes_for :quotations
end
class Quotation < ApplicationRecord
belongs_to :post
end The client has UI for updating an existing post with new quotations: {
type: 'post',
body: 'These are my favourite quotes:'
quotations: [
{
type: 'quotation',
id: 123,
body: 'Really old wisdom'
},
{
type: 'quotation',
body: 'Brand new insights'
},
]
} To serialize this into the JSON API format, quotations must be split into relationships and included: {
"type": "post",
"attributes": {
"body": "These are my favourite quotes:"
},
"relationships": {
"quotations": {
"data": [
{
"type": "quotation",
"id": "123" // Server-allocated id of existing Quotation
},
{
"type": "quotation",
"id": "cid_quote1" // Client id required to match with included below
}
]
}
},
"included": [
{
"id": "123",
"type": "quotation",
"attributes": {
"body": "Really old wisdom"
}
},
{
"id": "cid_quote1", // Required id to match with relationships above
"type": "quotation",
"attributes": {
"body": "Brand new insights"
}
}
]
}
params.from_jsonapi:
{
"post" => {
"body" => "These are my favourite quotes:",
"quotations_attributes" => {
"0" => {
"id" => "123",
"body" => "Really old wisdom"
},
"1" => { # No id is present, so ActiveRecord#update correctly creates the new instance
"body" => "Brand new insights"
}
}
} Without filtering out client ids: {
"post" => {
"body" => "These are my favourite quotes:",
"quotations_attributes" => {
"0" => {
"id" => "123",
"body" =>"Really old wisdom"
},
"1" => {
"id" => "cid_quote1", # Causes ActiveRecord to look for an existing Quotation with an id of "cid_quote1" - resulting in an ActiveRecord::RecordNotFound exception
"body" => "Brand new insights"
}
}
} |
Alright, got it. While I'm not yet sure about the design of blacklisting attributes with regexp, the idea of supporting creation and/or updating in the same request sounds like something that should be introduced. I'll allow myself some more time to think how we can handle this scenario and will get back to this issue in a few days. |
Ok, thanks for the consideration. If it helps, the way we are currently achieving the desired result in our custom handlers is to recursively delete matching ids from each attributes hash (by overriding But the way I was thinking of pursuing a more robust solution would be to simply omit them from being added to the attribute hashes or array of ids in the first place, at the point that each is built (removing the need for any recursive post-processing). |
Hi @Marahin, Did you get a chance to think about this? Thanks. |
Hey @greena13, indeed I have, but I couldn't think of a design that would work better than what you proposed. Could you open a PR with the change that would resolve the issue? |
Sure. It may be a while before I get one together, though. |
This is fantastic news, @nikajukic. @Marahin is there any chance of getting that pull request reviewed, merged and released any time soon? There's definitely still an appetite for it, on our end. |
@nikajukic @greena13 thanks for reaching out. Yes, we are working on reviewing the PR and this issue. There is an ongoing internal discussion at Visuality's open source commitee that should be followed by action on this matter. I can't give exact details nor date or time when this will happen, as I'm no longer part of the commitee but just supporting the maintenance and development of this gem, but I will do my best to keep it going so this can be resolved :) |
Thanks @Marahin, that's much appreciated. For what it's worth, I've taken a look over @nikajukic's PR and tried to provide some (hopefully) useful suggestions, to help keep this alive. |
Thank you for this library; it has saved us a lot of time.
If my reading of this previous issue is correct, it appears that initially this library started out with ignoring ids entirely, including those generated client-side, but support for ids was added for those who require it. However, I don't see an option to opt-out of this behaviour.
The spec permits ignoring client-generated IDs:
and it would seem the transforming functionality that
jsonapi_parameters
provides, is a natural (and efficient) point to do that.The particular issue we have is that we need
POST
andPATCH
requests that support "nested attributes", which as part of the client serialization process get split out intorelationships
andincluded
- necessitating client-generated ids to link them together until they're saved on the server and given server-allocated ids.However, we don't want these ids making their way to
ActiveRecord
methods likecreate
andupdate
(which erroneously cause Rails to attempt to find and update records with those ids - resulting inActiveRecord::RecordNotFound
exceptions being thrown).We can't simply ignore or reject client-generated ids as part of the Strong Parameters
permit
method, because ourPATCH
requests can include a mixture of client-generated ids (for new associated records) and server-side ids (for existing associated records).The solution we're currently going with is to define custom handlers for
to_one
andto_many
that strip out ids that are conformant with a particular convention for client-generated ids, but I suspect this is likely a use-case others may encounter and that it would be beneficial for the library to support a regular expression that would cause matching ids to be stripped out:Once I've confirm you may be receptive to such a feature, I don't mind working on a pull request.
Thanks.
The text was updated successfully, but these errors were encountered: