Git Product home page Git Product logo

meteor-publish-with-relations's Introduction

BREAKING CHANGES: This package does not automatically call the @ready() function anymore, that makes it easier to set up more than one relationships method.

This package is an updated version of tmeasday:publish-with-relations the key difference is support for arrays, nested arrays, a friendlier interface, and some bug fixes

API

this.relations(ops) (SERVER SIDE)

Used inside a Meteor.publish() function to define db relationships.

  • ops.collection: (REQUIRED)
    The anchor collection from which relations will be made.

  • ops.filter: (OPTIONAL)
    The object that filters the collection. This is the equivalent to filter in collection.find(filter).

  • ops.options: (OPTIONAL)
    The object that sorts and limits the collection. This is the equivalent to options in collection.find(filter,options).

  • ops.mappings: (OPTIONAL)
    An array of objects that maps relationships between collections using foreign_key and key

  • ops.mappings[].collection: (REQUIRED)
    Defines the collection that will be associated.

  • _ops.mappings[].foreign_key: (DEFAULT:"id")
    Defines the key to associate with at the parent collection.

  • _ops.mappings[].key: (DEFAULT:"id")
    Defines the key to associate with at the current collection.

  • ops.mappings[].filter: (OPTIONAL)
    The object that filters the collection. This is the equivalent to filter in collection.find(filter).

  • ops.mappings[].options: (OPTIONAL)
    The object that sorts and limits the collection. This is the equivalent to options in collection.find(filter,options).

Sample

Meteor.publish "things", ->
	if @userId #only publish when there's a user
		@relations
			collection:Things
			mappings:[
				{
					foreign_key:"sub_things.deep_things.deep_thing"
					collection:DeepThings
				}
				{
					foreign_key:"sub_things.sub_thing"
					collection:SubThings
				}
				{
					foreign_key:"other_thing"
					collection:OtherThings
				}
				{
					key:"thing"
					collection:ReverseThings
				}
			]

	# always call ready
	@ready()

This will publish all Things and their respective DeepThings, SubThings, OtherThings, and ReverseThings

IMPORTANT: When an association is broken, the package will stop all subscriptions to all broken associations but will not remove the association from the client. This means updates to the object with the broken association will not be recorded BUT the object will persist on the client. New associations will be published as expected. (This should not have an impact unless you are doing something with total published counts).

meteor-publish-with-relations's People

Contributors

lepozepo avatar svasva avatar tmeasday avatar dandv avatar jflecool2 avatar multiply avatar

Stargazers

Dead J. Dona avatar Andy Edwards avatar Kamil Dąbrowski avatar Carsten Meyer avatar Pat Moore avatar m_sharif avatar Walter Wu avatar Matthew avatar Josh Sherman avatar  avatar Jidé avatar

Watchers

James Cloos avatar  avatar

meteor-publish-with-relations's Issues

FR: Support multiple key fields

I currently can't do a mapping with two keys, eg

Transfer
  from: uid1
  to: uid2

mapping: [
  foreign_key: 'from'
  foreign_key: 'to'
  collection: Meteor.users
]

you have to duplicate the uids into an array, eg:

Transfer
  from: uid1
  to: uid2
  users: [uid1, uid2]

Perhaps this is because having multiple fields would not be performant compared to a single array field, in which case I withdraw the FR :)

Package publishes only the first ("father") collection

I Have a problem with the socialize:friendships package. I want to publish all and only my friends but I get the whole Meteor.users not only my friends. This is my code

Meteor.publish('myFriends', function () {
  if (this.userId) {
    this.relations({
      collection: Meteor.users,
      options: {fields :{profile: 1}},
      mappings: [
        {
          foreign_key: "friendId",
          collection: Meteor.friends,
          filter: {userId: this.userId},
        }
      ]
    });
  }
  return this.ready();
}); 

I don't get the Meteor.friends collection on the client and I get all Meteor.users. Is there something I'm missing?

Theese are my packages

[email protected]             # Packages every Meteor app needs to have
[email protected]       # Packages for a great mobile UX
[email protected]_1                   # The database Meteor supports right now
[email protected]    # Compile .html files into Meteor Blaze views
[email protected]            # Reactive variable for tracker
[email protected]                  # Helpful client-side library
[email protected]                 # Meteor's client-side reactive programming library

[email protected]_1    # JS minifier run for production mode
[email protected]_1                # ECMAScript 5 compatibility for older browsers.
[email protected]_1              # Enable ECMAScript2015+ syntax in app code
[email protected]            # Server-side component of the `meteor shell` command

[email protected]
momentjs:moment
fourseven:scss
mizzao:user-status
[email protected]
[email protected]
[email protected]
[email protected]
sacha:spin
raix:handlebar-helpers
[email protected]_1
kadira:flow-router
kadira:blaze-layout
tap:i18n
aldeed:template-extension
[email protected]
fortawesome:fontawesome
splendido:accounts-meld
mdg:geolocation
arillo:flow-router-helpers
useraccounts:flow-routing
useraccounts:materialize
[email protected]_1
rzymek:moment-locales
aldeed:autoform
aldeed:simple-schema
gildaspk:autoform-materialize
socialize:friendships
poetic:materialize-scss
gwendall:simple-schema-i18n
mdg:validated-method
audit-argument-checks
webtempest:animate
dburles:mongo-collection-instances
nimble:restivus
chuangbo:cookie
http
session
copleykj:jquery-autosize
ostrio:files
keepnox:perfect-scrollbar
lepozepo:publish-with-relations

List in an object does not iterate

I think I found a bug. I used the sample of this git.
Here's the data insertion:
thing_id = Things.insert({ name: "Thing " + thing, obj: { obj_list: [ { sub_thing: subthing } ] }, root_list: [ { sub_thing: subthing } ] });
You can see there's 2 arrays of subthings: one on the root of things and one in "obj", which is an object in things.
The root_list will work:
Meteor.publish("working", function() { this.relations({ collection: Things, filter: {}, mappings: [ { foreign_key: "root_list.sub_thing", collection: SubThings } ] }); return this.ready(); });

But the obj_list will not work:
Meteor.publish("notworking", function() { this.relations({ collection: Things, filter: {}, mappings: [ { foreign_key: "obj.obj_list.sub_thing", collection: SubThings } ] }); return this.ready(); });

Is it "by design" (technically, because how this package is working, it can't be fixed) or is it a bug?
Thanks
JF

Readme and versioning

Hi, I like the new API, looks cleaner! I found out about it because after updating, my app stopped working because subscriptions weren't becoming ready.

It's a good practice to change the major version number when making breaking change (http://semver.org/). So that:

  • a plain meteor update won't go from 1.2.3 to 2.0.0 so it doesn't update to an incompatible version
  • when I want to manually upgrade to a new major version, I know to look at the README to see what changes I would need to make

It would be nice to see an explanation @ top of README that included

  • instead of Meteor.publishWithRelations, use this.relations
  • no need for handle anymore
  • anything else I'm missing

Also, I just wanted to check – when you change from just doing Meteor.publishWithRelations to explicitly calling ready(), will it ever be the case that on the client, the subscription will say it's ready (sub.ready() == true) before the data arrives?

Clarify README example

Thanks for publishing this fork! I think it would be clearer if the example used more features and was on a topic, similar to the original package. I'm not sure what foreign_key:"sub_things.deep_things.deep_thing" means – is that a nested Mongodb object, or a series of keys, each in a different collection? For instance for this model:

Meteor.users
  _id
  profile
    name
      first
      last
    bioId

Posts
  userId

Comments
  postId
  userId

Is this correct?

# a user, their bio, their posts, their posts' most recent approved comments,
# and those comments' users
Meteor.publish "user", (userId) ->
  Meteor.publishWithRelations
    handle: this
    collection: Meteor.users
    filter: userId
    mappings: [
      {
        key: "profile.bioId"
        collection: Bios
      }
      {
        foreign_key: "userId"
        collection: Posts
        mappings: [
          {
            foreign_key: "postId"
            collection: Comments
            filter: { approved: true }
            options: {
              limit: 10,
              sort: { createdAt: -1 }
            }
            mappings: [
              {
                key: "userId"
                collection: Meteor.users
              }
            ]
          }
        ]
      }
    ]

Also, the README says there is support for arrays, but doesn't give an example of how that is formatted. This is an array of ids? Eg if the Posts/Comments relationship was changed to:

Posts
  userId
  comments # array of Comments._id

Comments
  userId

would the mapping be this?

{
  foreign_key: "userId"
  collection: Posts
  mappings: [
    {
      key: "comments"
      collection: Comments
    }
  ]
}

Published data returns ID for the related field

Hi!

I have this code:

Meteor.publish('leagues', function(){
this.relations({
collection: Leagues,
filter: {"abbrev": "test"},
mappings: [
{
foreign_key: "sport",
collection: Sports
}
]
})
this.ready();
// return Leagues.find({});
});

for the following collections:

Leagues

  • sport
  • name
  • abbrev
  • _id

Sport

  • name
  • status
  • _id

On subscription, the published data returns ID for Leagues.sport instead of the mapping above. What am I doing wrong?

Doesn't work with FS.collection

For some reason I can't map to FS.collections, I'm guessing something to do with added/changes/removed events?

might be nice to add a disclaimer in the readme if that's indeed the case

Meteor.publish('posts', function(id) {
  check(id, String);

  this.relations({
    collection: Meteor.posts,
    filter: {id: id},
    mappings: [
      {
        foreign_key: 'image',
        collection: Images
      }
    ]
  });

  return this.ready();
});

Images = new FS.Collection("images", {
stores: [new FS.Store.GridFS("images", {})],
filter: {
allow: {
contentTypes: ['image/*']
}
}
});

Thanks

Further readme explaination

Hi Lepozepo, thanks for maintaining this.

Can you explain what is means exactly to break an association.

IMPORTANT: When an association is broken, the package will stop all subscriptions to all broken associations but will not remove the association from the client. This means updates to the object with the broken association will not be recorded BUT the object will persist on the client. New associations will be published as expected. (This should not have an impact unless you are doing something with total published counts).

I'm having a problem with reactivity (server publishes full data, and client renders subset, and updates, then something happens in the middle which messes up the template, then data is consistent again, I'm thinking this may have something to do with it)

Thanks

How to reactive?

my publish is:

Meteor.publish('teachers', function(parameters) {
  if (this.userId) {
    this.relations({
      collection: UserAudit,
      filter: parameters.find,
      options: parameters.options,
      mappings: [
        {
          foreign_key: 'userId',
          collection: Meteor.users,
          options: "{'createdAt': 1, 'username': 1, 'service': 1, 'profile.name': 1, " +
            "'profile.gender': 1, 'profile.birthday': 1, 'profile.avatarUrl': 1}"
        }
      ]
    });
  }
  return this.ready();
});

when UserAudit field modified, client list not show the Meteor.users info;
when Meteor.users field modified, client list nothing unchanged.
How to reactive UserAudit Meteor.users ? thanks

Recursivity

Hello!
I came back to this Meteor package for doing something and was wondering if it should be possible: Recursivity. Lets say you want to subscribe to a tree of data, where all user has a list of childs. I tried something simple but didn't work (more than 1 stage). Is it possible and if yes where is my mistake:

Meteor.publish("userThings", function(userid) {
    this.relations({
        collection: Meteor.users,
        filter: {_id:userid},
        mappings: [

            {
                foreign_key: "child.child",
                collection:  Meteor.users
            },
            {
                foreign_key: "child",
                collection:  Meteor.users
            }
        ]
    });
    return this.ready();
});

Edit: Recursivity IS possible, just make Mapping reference itself:

Meteor.publish("commentsThings", function(anidplz) {
    var supermapping =
        {
            foreign_key: "child",
            collection: Comments
        };
    supermapping.mappings = [supermapping];

    this.relations({
        collection: Comments,
        filter: {_id:anidplz},
        mappings: [supermapping]
    });
    return this.ready();
});

Therefore I close this issue

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.