Sharing models via ember-cli addons?


#1

Let’s Say I have two ember-cli apps, main and admin. I have a model such as Product in the main application, and in the admin application I have a model ProductAdmin which extends the Product model and adds extra admin-only functionality.

What is the best way of sharing the Product model between the two apps? Is this something ember-cli addons are meant for?


Addon the correct way to share large percentage of code?
#2

Yes, this is absolutely something that addons are intended to help with.

Make an addon (easiest way is via ember addon my-product-models or some other way more imaginative name), and in that addon folder add a app/models/ folder that contains your shared models. Include that shared model addon with both applications (by adding it to package.json).

The files in app/ of the addon are merged with the ones in the applications app/ folder so that they end up at the same level in the module system.

Assuming that your addon had an app/models/foo.js file, and that you wanted to extend that from app/models/bar.js in your actual application you would do the following:

import Foo from './foo';

export default Foo.extend();

#3

Thanks for this answer Ryan.

Before I begin rearchitecting my existing app, I would like to understand how the development workflow might be If I am developing my models in a separate project to my actual ember-cli apps.

For example, after changing a model in the ‘common’ project, would I then have to run the ember-addon/npm install command to update both of my ember apps, or will both apps automatically get the latest model code from the common project?

Another thing - would it be possible to trigger livereload if I updated the model code in the common project, or would it require manual refreshes i.e can you tell ember-cli to watch for file changes in other directories.

Thanks again


#4

Hi there,

I can’t get the

import Foo from './foo';

thing to work. I have correctly created the addon and have the correct file name foo.js in the app/models folder of the addon project. The Foo is exporting a simple DS.Model file correctly aswell.

The project builds ok but the actual object Foo is undefined at runtime. Any ideas?

Funny thing is I’m using the same addon in both my main and admin projects, but only trying to extend it in the admin project. In the main project, it seems to discover the models and use them correctly, it’s just when I try to import them for extension that the exported object is undefined.


#5

Thank you for this post, as I was looking for the exact same thing. One question though: when you create an addon through ember cli, the bluepribt generates a folder addon and app. I’ve seen some people putting the code in app, and others in addon. What’s the difference between those two folders (as a side note, the blueprint for an addon seems really over engineered and complex)


#6

This is a good post explaining the difference between the addon and app folders in an addon:

http://edgycircle.com/blog/2014-creating-a-datepicker-ember-addon/


#7

Thank you, it makes sense :).


#8

Hi, first this is exactly what I want/need to do although … I’v got a few questions … Firstly if I want to achieve the following : gui-app depends on : model1-addon, model2-addon So Iv got a gui app that is using 2 different models … Ok so questions :

  1. each model-addon has a bunch of models, an adapter/serialiser and maybe store ?
  2. should the store be in parent gui app or is it ok in model-addon? If it’s in the model-addon how does it get injected in the parent gui app? so I can do my usual this.store.find in a routers model function. If its in the gui then how does the store know about the sub projects model??

Also, my linking between main app (gui) and add-on (model) is done with npm link in add on and then npm link model1-addon in the gui app. This works fine and I can see the sym link in my node_modules… but I had to add the “model1-addon” : “latest” to my package.json file … is this ok? And then, I’m guessing from what you wrote earlier I don’t need to include model1-addon to the gui-app’s bower.json? ember-cli automagically does it stuff with the npm link?

If I can get this working I have strong case against a project using angular … which would be nice … Look forward to your reply, Stephen.


#9

I actuallly have the same issue. I created the addon, and set it as a private dependency in my package.json in my consuming application. However I can’t seem to be able to use the models and any other code (it’s not even outputted in the dist file).


#10

My issue was that I was (stupidly) running

import Foo from './foo'

in a file named foo.js.

Make sure you’re not doing this!

If your issue is different you could post what you’re trying to do and tell us the structure of where your model files are, i.e are they in the /addon or /app folder in your addon project? I do have this working now and plan on blogging about it soon.


#11

Definitely not my issue. I have one addon where all the code is in the app folder. I’m using the blueprint from ember cli 0.1.0. It is NOT published on npm but is a private repository on github.

The other projects, the consumer, is an app created with ember cli 0.1. The addon has been added to package.json. I can see that it’s properly retrieved and appear on my node_modules folder, but it seems like the code is not merged and I cannot use any of the code in the addon. It does not appear neither in the compiled file.

I know it can works because we are using this mechanism in another app at work and my settings seem the same but does not work.


#12

Hey,

I would advise you to put all your actual ‘base’ models in the /addon/models folder of your addon project.

Then in your /app/models folder of your addon, simply import and export them like so,

// my-addon-models/app/models/mymodel.js
import MyModel from 'my-addon-models/models/mymodel';
export default MyModel;

now they will automatically get merged with your main application, yet you can still extend the models in your main app by using a file with the same name like:

In your actual app:

 #my-app/app/models/mymodel.js
 import MyModel from 'my-addon-models/models/mymodel';
 export default MyModel.extend({
      extraAttribute: DS.attr();
});

Now your extended version of MyModel will be used by Ember Data, and you can import it explicitly inside your app to use the extended functionality. This is exactly what I’m doing with my admin app.


#13

But if I understand it correctly that should be the default behavior when putting files in /app (no import and automatic merging). In my case this is exactly what I want, it’s not really an “add-on”, but it’s really part of my application. It’s not something reusable at all in other apps. I just need to have common models for client and admin parts :).


#14

If you put them in app/ (within the addon) you cannot augment the same model in the same location. Specifically, if you addon has app/models/foo.js and your consuming application has app/models/foo.js the consuming application file will always override the addon file. You have no opportunity to extend it.

The pattern suggested by @cjroebuck is absolutely the better way to go. You get the nice default merging, and you still have the ability to extend and augment.


#15

In that case, make sure your models folder is completely empty or non-existant in your main app project, otherwise you’re just going to clobber any models defined in the addons app/models folder.


#16

Thanks for the answer. I’m going to try that and I’ll let you know!


#17

Hi again @rwjblue,

After more thoughts, what I need in my case is really models in the app folder (I never need to extend them, and actually want to prevent that).

However, no matter how hard I try, I can’t make Ember-CLI load my addon. I can’t figure out why, because I’ve made another addon (published on NPM for the last one), and it works perfectly well. I tried to do a simple “alert” in the initialize, and while it works for the addon published on NPM, it does not for my private addon. It’s as the addon didn’t exist.

I’ve checked the configuration and they look perfectly similar. The “ember-addon” keyword is there in both cases… I can’t figure why it fails :/. Is there some hidden rules (like Ember-CLI not loading addons whose version is 0.0.0 or some obscure things like that ?)

EDIT : out of curiosity I tried placing the models into the addon folder, but they cannnot be found neither. I odn’t know why it happens like this. Maybe a conflict between the names ? (main app is called “my-app”, and addon is called “my-app-core” ?)


#18

@bakura it strange that you can’t load a local version of your addon.

Have you linked it and defined it in your package.json.

  "scripts": {
    "start": "ember server",
    "build": "ember build",
    "test": "ember test",
    "postinstall": "npm link ../my-addon",
    "postupdate": "npm link ../my-addon"
 },
 "devDependencies": {
   "my-addon": "0.0.1"
 {

#19

It actually works. If I remember it was because my addon had a version of 0.0.0. As soon as I bumped it to 0.0.1 it worked. I’m not sure this was the real reason, or if an update of ember cli made it works magically :slight_smile:


#20

Okay cool I also just found out you can add local dependency paths in npm 2.0

https://docs.npmjs.com/files/package.json#local-paths