Skip to content

Instantly share code, notes, and snippets.

@cullymason
Last active December 20, 2015 21:38
Show Gist options
  • Save cullymason/6198667 to your computer and use it in GitHub Desktop.
Save cullymason/6198667 to your computer and use it in GitHub Desktop.
It would be nice if we had a plugin that allows Laravel to play nice with Ember. Put simply I would like to create an easy way for Laravel to output JSON strings in a way that Ember likes.

Basic Explaination

It would be nice if we had a plugin that allows Laravel to play nice with Ember. Put simply I would like to create an easy way for Laravel to output JSON strings in a way that Ember likes.

What Laravel Does

return Model::find($id);

// OR

return Model::all();

You are returned a raw json object like so:

//One Model
{"id": 1, "other attribute": "something"}

// Array of Models
[{"id": 2, "other attribute": "something"},{"id": 3, "other attribute": "something"},{"id": 1, "other attribute": "something"}]

What Ember expects

{ "model": {"id": 1, "otherAttribute": "something"} }

or

{ "models": [{"id": 2, "otherAttribute": "something"},{"id": 3, "otherAttribute": "something"},{"id": 1, "otherAttribute": "something"}] }

The code to make this work really is not that bad:

return $a['model'] = Model::find($id)->toArray();

Relationship Overload

But it gets increasingly cumbersome and repetitive when relationships are added into the mix.

For example, if a post has many comments, Ember wants JSON to to be returned like so:

{
	"post": {"id": 1,"post_title":"This is a title", "text":"post text","comments": [1,2,3]},
	"comments":[
		{"id":1,"post_id:"1","text":"test"},
		{"id":2,"post_id:"1","text":"test"},
		{"id":3,"post_id:"1","text":"test"}]
}

It would be nice if there was a way to type:

return Post::find($id)->ember();

or maybe...

$post = Post::find($id);
return Response::ember($post);

to return just the model and then to sideload relationships:

return Post::find($id)->ember()->sideload('comments');

to return

{
	"post": {"id": 1,"post_title":"This is a title", "text":"post text","comments": [1,2,3]},
	"comments":[
		{"id":1,"post_id:"1","text":"test"},
		{"id":2,"post_id:"1","text":"test"},
		{"id":3,"post_id:"1","text":"test"}]
}

And it automatically does a few things:

  • creates a json string in the format of "{model_name: {json representation of that model}}
  • somehow distinguish if there are any relationships associated with that model
  • if there are:
    • Add their ids to the Model's JSON string
    • create a json array of all of those relationships
    • and recursively add ids and json arrays if those relationships have them (For example,if a category has posts and those posts have comments)

Thoughts?

Possible process of how the command would work

  • get the lowercase model name
    • pluralize if it returns more than one item (ie Model::all->ember())
  • check to see if the model has any relationships
    • if Belongs to:
      • get the singular name of the related model
      • the id of the related model
      • add the related model to the original model like so model:id
    • if Has Many:
      • get the plural name of the related model
      • the ids of the related model
      • add the related model to the original model like so mode:[id,id,id]
  • go through the different properties of the model and change from snake case to camel case (except for the relationship id property)
  • create json string that follows this pattern:{ "Model(s)": "property":"property value",..., "relationship(s)": id }
  • if the request asks for the sideload command (maybe: Model::all()->ember()->sideload(), the related models would be added to the json string following the same process as the original model.
@BenjaminRosell
Copy link

Good call. I wish there was an ember method with Eloquent, but I doubt it will be implemented by the core team. I guess it can be done through a base model...

Let me give it a try. I'll keep you updated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment