0

i have a search model like this (got this from https://github.com/maccman/quora2)

Spine = require('spine')

classMethods = 
  query: (params) ->
    @select (rec) ->
      rec.query params

instanceMethods =
  query: (params) ->
    attributes = @query_atts?() || @attributes()
    for key of attributes
      value = attributes[key]
      if value?.query?(params).length
        return true
      else if value && typeof value == "string"
        value = value.toLowerCase()
        return true if value.indexOf(params) != -1
    return false

class Search extends Spine.Class
  @include Spine.Events

Search.Model = 
  extended: ->
    @extend  classMethods
    @include instanceMethods

Search.include
  init: (models...) ->
    console.log('models: ', models)
    @models  = models
    @results = []

  query: (params) ->
    @clear()
    return unless params
    @params = params.toLowerCase()
    @models.forEach (model) =>
      console.log(typeof(model))
      continue until typeof(model) == 'undefined'
      results  = model.query(@params)
      @results = @results.concat(results)

    @trigger "change"

  clear: ->
    @results = []
    @trigger "change"

  each: (callback) ->
    @results.forEach(callback)

module.exports = Search

and a Page model:

Spine = require('spine')

class Page extends Spine.Model
  @configure 'Page', 'title', 'description'

  @extend require('models/search').Model

  constructor: ->
    super

module.exports = Page

the issue i have is that whenever is instantiate a Search in my controller:

Search.init(Page) and log what init gets as arguments i have the Page as a first argument and then i have 4 undefined.

models:  [Page(title, description), undefined, undefined, undefined, undefined]

where do these come from? of course it works fine in quora and it would work fine if i would not use models... in the init.

aschmid00
  • 7,038
  • 2
  • 47
  • 66

1 Answers1

2

When you call

Search.init

that invokes the Module.init method, defined in Spine like so:

Module.init = Controller.init = Model.init = (a1, a2, a3, a4, a5) ->
  new this(a1, a2, a3, a4, a5)

(Note that Spine.Class = Module.) That then invokes the Search constructor inherited from Module, which forwards all those arguments to the init method that Search.include attached to the Search prototype:

constructor: ->
  @init?(arguments...)

Hence the four undefined arguments (originally a2, a3, a4, and a4).

Trevor Burnham
  • 76,828
  • 33
  • 160
  • 196
  • that makes sense. so how should i implement it so that my init works as i actually expect? and what is of having 5 arguments defined in Module.init by default? – aschmid00 May 16 '12 at 20:02
  • It seems to me that you should simply be using `new Search(Page)` rather than `Search.init(Page)`. If I understand correctly, the reason why calling `init` on the class is preferred is that you can override it and thus respond to instantiation at the class level; but you aren't doing this, so using `Search.init` does nothing but add noise. – Trevor Burnham May 18 '12 at 03:23
  • the thing is that search is implemented as it is here https://github.com/maccman/quora2/blob/master/app/models/search.coffee#L26 and unless i modify how the Search model is initialized i can't pass the model directly to the class – aschmid00 May 18 '12 at 13:35
  • Not sure what you're saying. The prototypal `init` is called from the constructor, so that's still going to happen if you use `new Search(Page)`. – Trevor Burnham May 18 '12 at 20:26
  • so i have to say im not a js guru so everything i could not be right. i tried to pass in Page directly but that did not work but i might do something wrong... – aschmid00 May 18 '12 at 20:52