Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to prevent Ember Data from saving attribute (ie., Read-only attribute)

I am creating an online form builder using Ember 2.0 on the front-end and Rails 4.2 on the back-end with the json_api_resources gem.

In the process of publishing a form, a user must be able to cut/paste a snippet of code into his/her webpage in order to 'ajax in' the form they have configured.

Thus the 'embed-snippet' attribute of the Form model should be read-only. I do not want the contents of the snippet field to be sent back to the server when the user makes a change to the form and re-saves the record.

Some approaches I have considered:

  • Modifying the serializer to check for this specific attribute and drop it from the payload before sending it to the back-end
  • Converting the 'embed-snippet' field to a separate model with a relationship to the Form model, and then excluding it somehow from the save
  • Creating a new Ember Data attribute type

Ideally there would be a better way to deal with this problem.

Something like:

'DS.attr('string', { readOnly: true })

So my question is, what is the best way to ensure the content of this field does not get sent back to the server?

like image 244
Christopher Milne Avatar asked Sep 28 '15 18:09

Christopher Milne


3 Answers

To get the { readOnly: true } functionality (which makes it easier to add new models/attrs) you can customize the serializeAttribute method on the JSONAPISerializer:

(in serializers/application.js):

import DS from 'ember-data';

export default DS.JSONAPISerializer.extend({
  serializeAttribute(snapshot, json, key, attribute) {
    // do not serialize the attribute!
    if (attribute.options && attribute.options.readOnly) {
      return;
    }
    this._super(...arguments);
  },
});
like image 123
bokonic Avatar answered Nov 11 '22 12:11

bokonic


The easiest way to do this is to create a custom serializer for the form model and use the attrs property to prevent the attribute from being serialized.

In app/serializers/form.js:

export default DS.JSONAPISerializer.extend({
    attrs: {
        embedSnippet: { serialize: false }
    }
});

For more information and examples on attrs see the API documentation http://emberjs.com/api/data/classes/DS.JSONSerializer.html#property_attrs

like image 28
bmac Avatar answered Nov 11 '22 13:11

bmac


You can also control this from the backend, using json-api-resources. In whatever the appropriate resource file is, you can control which attributes are allowed to be retrieved from the backend and which attributes are allowed to be accepted by the backend. Like so:

def self.fetchable_fields(context)
  super - [
    :whatever_attribute_not_to_fetch_from_backend
  ]
end

def self.creatable_fields(context)
  super - [
    :embed_snippet,
    :another_attribute_not_accepted_from_post
  ]
end

This may not be what you're looking for since it won't prevent the attributes from being sent to the backend, but rather prevents them from being accepted. But it's another option.


UPDATE

Depending on your use case, you may also need to use this:

def self.updatable_fields(context)
  super - [:whatever]
end
like image 20
jeffdill2 Avatar answered Nov 11 '22 13:11

jeffdill2