7

Rails have Nested Resources for a while, and it has been heavy used (or overused). Say we have two model, Article and Comment.

class Article < ActiveRecord::Base
  has_many :comments
end

class Comment < ActiveRecord::Base
  belongs_to :article
end

Define the Nested Resource in routes.rb

resources :articles do
  resources :comments
end

So now, we can list comments by specific article: http://localhost:3000/articles/1/comments

But Spine can only make url for post request to create Article and Comment like this:

/articles
/comments

How to make Spine's url for Ajax request like this?

/articles/1/comments

I know I can override the url() in Comment Model for retrieval comments, but what about creating a new record?

I also go through the source code as well, what I found is that the create() method in Spine's Ajax module doesn't care about the custom url() function in instance of Comment. what I want is just pass the article_id and using it with my custom url() function to generate url, then I can posting to server for create.

Does it possible without fork and modified version of Spine fo my own?

btw: sorry for my English, wish all of you guys can understand what I want to say about :-)

Thank you and best regards,

Daniel Lv
  • 867
  • 6
  • 10

5 Answers5

2

The model's url property can be a value or a function. So you could do:

class Comment extends Spine.Model
  @configure "comment", "article_id"
  @extend Spine.Model.Ajax

  @url: ->
    "articles/#{article_id}/comments"

or something similar. The ajax module will evaluate this property and use it as the resource end point when building requests.

Dane O'Connor
  • 75,180
  • 37
  • 119
  • 173
  • As Daniel says in the question, this does not work for creation. – Pelle Jan 07 '12 at 22:30
  • This doesn't work for create URL's since the Ajax.getURL function is passed the Comment model and not an instance of a comment. So it has no clue what an article_id is. Check my answer :) – SpoBo Feb 15 '12 at 15:58
2

add

#= require spine/relation

to app/javascript/app/views/index.js.cofee

to add the relation extension

class App.Project extends Spine.Model
  @configure 'Project', 'name'
  @extend Spine.Model.Ajax
  @hasMany 'pages', 'projects/page'

class App.Page extends Spine.Model
  @configure 'Page', 'name', 'content'
  @extend Spine.Model.Ajax
  @belongsTo 'project', 'Project'

in javascript console

App.Project.find(the_id).pages().create({name:"asd"})

more info in http://spinejs.com/docs/relations

the link is at the bottom of spinejs model documentation

wizztjh
  • 6,979
  • 6
  • 58
  • 92
2

I have a solution:

http://groups.google.com/group/spinejs/browse_thread/thread/6a5327cdb8afdc69?tvc=2

https://github.com/SpoBo/spine

I made a fork which overrides how url's are generated in the ajax module. This allows the create url to contain bits of the model's instance data. For example: /articles/1/comments. Works with create, update, etc.

class App.Post extends Spine.Model 
  @configure 'Post', 'channel_id', 'title' 
  @extend Spine.Model.Ajax 

  resourceUrl: -> 
    "channels/#{@channel_id}/posts" 

  @hasOne 'channel', 'App.Channel' 
SpoBo
  • 2,100
  • 2
  • 20
  • 28
0

Following bit of code worked for me BUT then it didn't...(and I modified this answer). So this is NOT a good solution because Ajax-requests are queued by Spine. It always worked for a first comment but not for subsequent calls since the call to super would return without having sent the PUT/POST.

class Comment extends Spine.Model
  @configure "comment", "article_id"
  @extend Spine.Model.Ajax

  # hack for nested: @article_id is only set correctly during save
  @article_id = "?"
  @url: =>"/articles/#{@article_id}/comments"

  save: ()=>
    # hack for nested resources (see @url)
    Comment.article_id = @article_id
    super
    Comment.article_id = "?"
Enceradeira
  • 387
  • 4
  • 15
0

I have the same problem as this seems to be one of the biggest problems with Spine.

It is fairly straightforward to implement with BackBone due to it's simplicity, but Spine's internals are quite complex making it quite difficult.

I am trying to implement stand will come back if I have a solution.

Pelle
  • 455
  • 2
  • 4