0

I'd like to be able to inject my Session singleton into my Ember models. The use case I'm trying to support is having computed properties on the model that react to the user's profile (a property on the Session object).

App = window.App = Ember.Application.create({
    ready: function() {
       console.log('App ready');
       this.register('session:current', App.Session, {singleton: true});
       this.inject('session:current','store','store:main');
       this.inject('controller','session','session:current');
       this.inject('model','session','session:current');
    }
});

The injection works fine into the controller but I'm having trouble with getting it to the model. Is there any limitation here? Any special techniques?

-------- Additional Context ---------

Here's an example of what I'd like to be able to do in my model definition:

App.Product = DS.Model.extend({
    name: DS.attr("string"),
    company: DS.attr("string"),
    categories: DS.attr("raw"),
    description: DS.attr("string"),

    isConfigured: function() {
        return this.session.currentUser.configuredProducts.contains(this.get('id'));
    }.property('id')
}); 
Marcio Junior
  • 19,078
  • 4
  • 44
  • 47
ken
  • 8,763
  • 11
  • 72
  • 133

1 Answers1

11

By default injections in models don't work. To do so you need to set the flag Ember.MODEL_FACTORY_INJECTIONS = true:

Ember.MODEL_FACTORY_INJECTIONS = true;

App = window.App = Ember.Application.create({
    ready: function() {
       console.log('App ready');
       this.register('session:current', App.Session, {singleton: true});
       this.inject('session:current','store','store:main');
       this.inject('controller','session','session:current');
       this.inject('model','session','session:current');
    }
});

The downside of this, is that it create some break changes:

  • If you have App.Product.FIXTURES = [...] you neeed to use App.Product.reopenClass({ FIXTURES: [...] });

  • productRecord.constructor === App.Product will evaluate to false. To solve this you can use App.Product.detect(productRecord.constructor).

Marcio Junior
  • 19,078
  • 4
  • 44
  • 47
  • Uggh. Unfortunately setting this property also breaks the debuggers ability to see the loaded models (aka, they all stay set at zero). – ken Nov 15 '13 at 18:11
  • Is there any other way to get my `Session` object into the computed property of the model? – ken Nov 15 '13 at 18:12
  • Loaded models? Sorry, I don't get your problem – Marcio Junior Nov 15 '13 at 18:15
  • The `Session` singleton has a `currentUser` property that I want to access within the model's `isConfigured()` computed property (listed above). I was going to use injection to get the reference but if there's another way I'm open to it. – ken Nov 15 '13 at 18:17
  • IMO the injection is the better way, because you don't create dependency on globals, like: `App.session.currentUser`. But if you want is possible to use it `App.session.currentUser`, and reference where needed. – Marcio Junior Nov 15 '13 at 18:35
  • Not sure I'm being clear ... I'm trying to avoid global scope. I am using injection for session (in a controller I access it by `this.session`). That's working. Now what I want is the model to gain a reference to the session information as well (specifically the `currentUser` property off of session). If I were using the global `App.session` approach then I could solve this very easily. What I'm struggling with is how to use injection to solve this. – ken Nov 15 '13 at 18:41
  • Isn't your fault my english isn't good thinking :). But what is the problem with `this.session` in your model, is it undefined? Or seems like a bad way to solve this in your opinion? – Marcio Junior Nov 15 '13 at 18:56
  • `this.session` is an injected variable for session state (e.g., accessToken, userId, etc.). See the code above, I think it illustrates it's origin. Anyway, I believe it is the leading pattern for managing session state and it is in contrast to the the declaration of a globally accessible App.Session object. My frustration is that I want to trigger off of the current user's profile which passed to the controllers through injection but I don't know of a good way to access it in a model's implementation. Your original suggestion may work but if it breaks the debugger than the cost is too high. – ken Nov 15 '13 at 20:18
  • The only breakchange is the record class identity, I don't think it's a problem unless if you have a big app. Right now I thought in another solution: move the `isConfigured` computed property to a controller, so no breakchanges in your app. Please give a look http://jsfiddle.net/marciojunior/aze96/ – Marcio Junior Nov 16 '13 at 03:15
  • Or just put your model inside an Ember.Object :) – Steffen Brem Apr 10 '14 at 12:10