mongoid / mongoid-slug

Generates a URL slug/permalink based on fields in a Mongoid-based model.
https://github.com/mongoid/mongoid-slug
MIT License
493 stars 163 forks source link

NoMethodError: undefined method `slug' error #80

Closed calicoder closed 12 years ago

calicoder commented 12 years ago

Slug seems to be undefined for a model attribute that has been slugged.

>> Member.last.slug
NoMethodError: undefined method `slug' for #<Member:0x007ffd4499eff0>
    from /Users/andy/.rvm/gems/ruby-1.9.3-p125@myapp/gems/mongoid-3.0.5/lib/mongoid/attributes.rb:225:in `method_missing'
    from (irb):22
    from /Users/andy/.rvm/gems/ruby-1.9.3-p125@myapp/gems/railties-3.2.2/lib/rails/commands/console.rb:47:in `start'
    from /Users/andy/.rvm/gems/ruby-1.9.3-p125@myapp/gems/railties-3.2.2/lib/rails/commands/console.rb:8:in `start'
    from /Users/andy/.rvm/gems/ruby-1.9.3-p125@myapp/gems/railties-3.2.2/lib/rails/commands.rb:41:in `<top (required)>'
    from script/rails:6:in `require'
    from script/rails:6:in `<main>'

Also, I get this error when trying to set the username, which is slugged.

>> m = Member.last
>> m.username = "badninja"
>> m.save
NoMethodError: undefined method `username' for "badninja":String
    from /Users/andy/workspace/myapp/app/models/member.rb:51:in `block in <class:Member>'
    from /Users/andy/.rvm/gems/ruby-1.9.3-p125@myapp/bundler/gems/mongoid-slug-0294c663c42b/lib/mongoid/slug.rb:111:in `call'
    from /Users/andy/.rvm/gems/ruby-1.9.3-p125@myapp/bundler/gems/mongoid-slug-0294c663c42b/lib/mongoid/slug.rb:111:in `find_unique_slug_for'
    from /Users/andy/.rvm/gems/ruby-1.9.3-p125@myapp/bundler/gems/mongoid-slug-0294c663c42b/lib/mongoid/slug.rb:272:in `find_unique_slug_for'
    from /Users/andy/.rvm/gems/ruby-1.9.3-p125@myapp/bundler/gems/mongoid-slug-0294c663c42b/lib/mongoid/slug.rb:303:in `find_unique_slug'
    from /Users/andy/.rvm/gems/ruby-1.9.3-p125@myapp/bundler/gems/mongoid-slug-0294c663c42b/lib/mongoid/slug.rb:256:in `build_slug'
    from /Users/andy/.rvm/gems/ruby-1.9.3-p125@myapp/gems/activesupport-3.2.2/lib/active_support/callbacks.rb:407:in `_run__1994561856913203917__save__2219248855043090796__callbacks'
    from /Users/andy/.rvm/gems/ruby-1.9.3-p125@myapp/gems/activesupport-3.2.2/lib/active_support/callbacks.rb:405:in `__run_callback'
    from /Users/andy/.rvm/gems/ruby-1.9.3-p125@myapp/gems/activesupport-3.2.2/lib/active_support/callbacks.rb:385:in `_run_save_callbacks'
    from /Users/andy/.rvm/gems/ruby-1.9.3-p125@myapp/gems/activesupport-3.2.2/lib/active_support/callbacks.rb:81:in `run_callbacks'
    from /Users/andy/.rvm/gems/ruby-1.9.3-p125@myapp/gems/mongoid-3.0.5/lib/mongoid/callbacks.rb:100:in `run_callbacks'
    from /Users/andy/.rvm/gems/ruby-1.9.3-p125@myapp/gems/mongoid-3.0.5/lib/mongoid/persistence/modification.rb:23:in `prepare'
    from /Users/andy/.rvm/gems/ruby-1.9.3-p125@myapp/gems/mongoid-3.0.5/lib/mongoid/persistence/operations/update.rb:43:in `persist'
    from /Users/andy/.rvm/gems/ruby-1.9.3-p125@myapp/gems/mongoid-3.0.5/lib/mongoid/persistence.rb:139:in `update'
    from /Users/andy/.rvm/gems/ruby-1.9.3-p125@myapp/gems/mongoid-3.0.5/lib/mongoid/persistence.rb:81:in `save'
    from (irb):25
    from /Users/andy/.rvm/gems/ruby-1.9.3-p125@myapp/gems/railties-3.2.2/lib/rails/commands/console.rb:47:in `start'
    from /Users/andy/.rvm/gems/ruby-1.9.3-p125@myapp/gems/railties-3.2.2/lib/rails/commands/console.rb:8:in `start'
    from /Users/andy/.rvm/gems/ruby-1.9.3-p125@myapp/gems/railties-3.2.2/lib/rails/commands.rb:41:in `<top (required)>'
    from script/rails:6:in `require'

This is the model:

class Member 
  include Mongoid::Document
  include Mongoid::Slug

  field :username, type: String
  slug :username
end

This is my gemlock:


GIT
  remote: git://github.com/calicoder/active_shipping
  revision: b82cfac222e478c3a90647e0203f9677359ef2f7
  specs:
    active_shipping (0.9.14)
      active_utils (>= 1.0.1)
      activesupport (>= 2.3.5)
      builder
      i18n
      json (>= 1.5.1)

GIT
  remote: git://github.com/digitalplaywright/mongoid-slug.git
  revision: 0294c663c42bb7581578b0cbb99d145b82adf472
  specs:
    mongoid_slug (0.20.0)
      mongoid (~> 3.0.0)
      stringex (~> 1.4)

GIT
  remote: git://github.com/thoughtbot/paperclip.git
  revision: 4bea897fa277eb3928442826e1098108590d9b0b
  specs:
    paperclip (3.1.4)
      activemodel (>= 3.0.0)
      activerecord (>= 3.0.0)
      activesupport (>= 3.0.0)
      cocaine (>= 0.0.2)
      mime-types

GIT
  remote: https://github.com/37signals/mail_view.git
  revision: 86a56c55143b3688add21ac95946c008df32c491
  specs:
    mail_view (1.0.1)
      tilt

GEM
  remote: https://rubygems.org/
  specs:
    actionmailer (3.2.2)
      actionpack (= 3.2.2)
      mail (~> 2.4.0)
    actionpack (3.2.2)
      activemodel (= 3.2.2)
      activesupport (= 3.2.2)
      builder (~> 3.0.0)
      erubis (~> 2.7.0)
      journey (~> 1.0.1)
      rack (~> 1.4.0)
      rack-cache (~> 1.1)
      rack-test (~> 0.6.1)
      sprockets (~> 2.1.2)
    active_utils (1.0.4)
      activesupport (>= 2.3.11)
      i18n
    activemodel (3.2.2)
      activesupport (= 3.2.2)
      builder (~> 3.0.0)
    activerecord (3.2.2)
      activemodel (= 3.2.2)
      activesupport (= 3.2.2)
      arel (~> 3.0.2)
      tzinfo (~> 0.3.29)
    activeresource (3.2.2)
      activemodel (= 3.2.2)
      activesupport (= 3.2.2)
    activesupport (3.2.2)
      i18n (~> 0.6)
      multi_json (~> 1.0)
    addressable (2.3.2)
    arel (3.0.2)
    asset_sync (0.5.0)
      activemodel
      fog
    awesome_print (1.0.2)
    aws-s3 (0.6.3)
      builder
      mime-types
      xml-simple
    aws-sdk (1.3.9)
      httparty (~> 0.7)
      json (~> 1.4)
      nokogiri (>= 1.4.4)
      uuidtools (~> 2.1)
    bcrypt-ruby (3.0.1)
    blankslate (2.1.2.4)
    bson (1.7.0)
    bson_ext (1.7.0)
      bson (~> 1.7.0)
    builder (3.0.0)
    cancan (1.6.8)
    capybara (1.1.2)
      mime-types (>= 1.16)
      nokogiri (>= 1.3.3)
      rack (>= 1.0.0)
      rack-test (>= 0.5.4)
      selenium-webdriver (~> 2.0)
      xpath (~> 0.1.4)
    childprocess (0.3.5)
      ffi (~> 1.0, >= 1.0.6)
    chunky_png (1.2.6)
    cocaine (0.3.0)
    coffee-rails (3.2.2)
      coffee-script (>= 2.2.0)
      railties (~> 3.2.0)
    coffee-script (2.2.0)
      coffee-script-source
      execjs
    coffee-script-source (1.3.3)
    compass (0.12.2)
      chunky_png (~> 1.2)
      fssm (>= 0.2.7)
      sass (~> 3.1)
    compass-rails (1.0.3)
      compass (>= 0.12.2, < 0.14)
    crack (0.3.1)
    css_parser (1.2.6)
      addressable
      rdoc
    dalli (2.1.0)
    database_cleaner (0.8.0)
    delayed_job (3.0.3)
      activesupport (~> 3.0)
    delayed_job_mongoid (2.0.0)
      delayed_job (~> 3.0)
      mongoid (~> 3.0)
    devise (2.1.2)
      bcrypt-ruby (~> 3.0)
      orm_adapter (~> 0.1)
      railties (~> 3.1)
      warden (~> 1.2.1)
    devise-encryptable (0.1.1)
      devise (>= 2.1.0.rc)
    diff-lcs (1.1.3)
    ejs (1.0.0)
    erubis (2.7.0)
    exception_notification (2.6.1)
      actionmailer (>= 3.0.4)
    excon (0.16.2)
    execjs (1.4.0)
      multi_json (~> 1.0)
    factory_girl (4.0.0)
      activesupport (>= 3.0.0)
    factory_girl_rails (4.0.0)
      factory_girl (~> 4.0.0)
      railties (>= 3.0.0)
    faker (1.0.1)
      i18n (~> 0.4)
    faraday (0.8.4)
      multipart-post (~> 1.1)
    fast-stemmer (1.0.1)
    ffi (1.1.5)
    fog (1.5.0)
      builder
      excon (~> 0.14)
      formatador (~> 0.2.0)
      mime-types
      multi_json (~> 1.0)
      net-scp (~> 1.0.4)
      net-ssh (>= 2.1.3)
      nokogiri (~> 1.5.0)
      ruby-hmac
    formatador (0.2.3)
    fssm (0.2.9)
    growl (1.0.3)
    guard (1.3.2)
      listen (>= 0.4.2)
      thor (>= 0.14.6)
    guard-bundler (1.0.0)
      bundler (~> 1.0)
      guard (~> 1.1)
    guard-coffeescript (1.2.0)
      coffee-script (>= 2.2.0)
      guard (>= 1.1.0)
    guard-rails-assets (0.1.3)
      guard
      rails (>= 3.1.1)
      rake
    guard-rspec (1.2.1)
      guard (>= 1.1)
    haml (3.1.7)
    haml_coffee_assets (1.4.6)
      coffee-script (>= 1.0.0)
      sprockets (>= 2.0.3)
      tilt (>= 1.3.3)
    hashie (1.2.0)
    hike (1.2.1)
    httparty (0.8.3)
      multi_json (~> 1.0)
      multi_xml
    httpauth (0.1)
    i18n (0.6.1)
    jbuilder (0.4.3)
      activesupport (>= 3.0.0)
      blankslate (>= 2.1.2.4)
    journey (1.0.4)
    jquery-rails (2.1.1)
      railties (>= 3.1.0, < 5.0)
      thor (~> 0.14)
    json (1.6.7)
    jsonschema (2.0.2)
    jwt (0.1.5)
      multi_json (>= 1.0)
    kgio (2.7.4)
    libwebsocket (0.1.5)
      addressable
    listen (0.4.7)
      rb-fchange (~> 0.0.5)
      rb-fsevent (~> 0.9.1)
      rb-inotify (~> 0.8.8)
    mail (2.4.4)
      i18n (>= 0.4.0)
      mime-types (~> 1.16)
      treetop (~> 1.4.8)
    mime-types (1.19)
    money (5.0.0)
      i18n (~> 0.4)
      json
    mongoid (3.0.5)
      activemodel (~> 3.1)
      moped (~> 1.1)
      origin (~> 1.0)
      tzinfo (~> 0.3.22)
    mongoid-paperclip (0.0.7)
      paperclip (>= 2.3.6)
    mongoid_search (0.3.0)
      fast-stemmer (~> 1.0.0)
      mongoid (>= 3.0.0)
    mongoid_token (1.1.0)
      mongoid (~> 3.0)
    moped (1.2.1)
    multi_json (1.3.6)
    multi_xml (0.5.1)
    multipart-post (1.1.5)
    net-scp (1.0.4)
      net-ssh (>= 1.99.1)
    net-ssh (2.5.2)
    newrelic_rpm (3.4.1)
    nokogiri (1.5.5)
    oauth2 (0.8.0)
      faraday (~> 0.8)
      httpauth (~> 0.1)
      jwt (~> 0.1.4)
      multi_json (~> 1.0)
      rack (~> 1.2)
    omniauth (1.1.1)
      hashie (~> 1.2)
      rack
    omniauth-facebook (1.4.1)
      omniauth-oauth2 (~> 1.1.0)
    omniauth-oauth2 (1.1.0)
      oauth2 (~> 0.8.0)
      omniauth (~> 1.0)
    origin (1.0.7)
    orm_adapter (0.4.0)
    paypal_adaptive (0.3.0)
      json (~> 1.6.0)
      jsonschema (~> 2.0.0)
      rake (~> 0.8)
    polyglot (0.3.3)
    powder (0.1.8)
      thor (>= 0.11.5)
    pusher (0.9.4)
      multi_json (~> 1.0)
      signature (~> 0.1.2)
    rack (1.4.1)
    rack-cache (1.2)
      rack (>= 0.4)
    rack-rewrite (1.2.1)
    rack-ssl (1.3.2)
      rack
    rack-test (0.6.1)
      rack (>= 1.0)
    rails (3.2.2)
      actionmailer (= 3.2.2)
      actionpack (= 3.2.2)
      activerecord (= 3.2.2)
      activeresource (= 3.2.2)
      activesupport (= 3.2.2)
      bundler (~> 1.0)
      railties (= 3.2.2)
    rails-backbone (0.7.2)
      coffee-script (~> 2.2.0)
      ejs (~> 1.0.0)
      railties (>= 3.1.0)
    railties (3.2.2)
      actionpack (= 3.2.2)
      activesupport (= 3.2.2)
      rack-ssl (~> 1.3.2)
      rake (>= 0.8.7)
      rdoc (~> 3.4)
      thor (~> 0.14.6)
    raindrops (0.10.0)
    rake (0.9.2.2)
    rb-fchange (0.0.5)
      ffi
    rb-fsevent (0.9.1)
    rb-inotify (0.8.8)
      ffi (>= 0.5.0)
    rdoc (3.12)
      json (~> 1.4)
    remotipart (1.0.2)
    roadie (2.3.2)
      actionmailer (> 3.0.0, < 3.3.0)
      css_parser
      nokogiri (>= 1.4.4)
      sprockets
    rr (1.0.4)
    rspec (2.9.0)
      rspec-core (~> 2.9.0)
      rspec-expectations (~> 2.9.0)
      rspec-mocks (~> 2.9.0)
    rspec-core (2.9.0)
    rspec-expectations (2.9.1)
      diff-lcs (~> 1.1.3)
    rspec-mocks (2.9.0)
    rspec-rails (2.9.0)
      actionpack (>= 3.0)
      activesupport (>= 3.0)
      railties (>= 3.0)
      rspec (~> 2.9.0)
    ruby-hmac (0.4.0)
    rubyzip (0.9.9)
    sass (3.2.1)
    sass-rails (3.2.5)
      railties (~> 3.2.0)
      sass (>= 3.1.10)
      tilt (~> 1.3)
    selenium-webdriver (2.25.0)
      childprocess (>= 0.2.5)
      libwebsocket (~> 0.1.3)
      multi_json (~> 1.0)
      rubyzip
    shoulda-matchers (1.3.0)
      activesupport (>= 3.0.0)
    signature (0.1.4)
    simple_form (2.0.2)
      actionpack (~> 3.0)
      activemodel (~> 3.0)
    simplecov (0.6.4)
      multi_json (~> 1.0)
      simplecov-html (~> 0.5.3)
    simplecov-html (0.5.3)
    sprockets (2.1.3)
      hike (~> 1.2)
      rack (~> 1.0)
      tilt (~> 1.1, != 1.3.0)
    state_machine (1.1.2)
    stringex (1.4.0)
    thor (0.14.6)
    tilt (1.3.3)
    treetop (1.4.10)
      polyglot
      polyglot (>= 0.3.1)
    tzinfo (0.3.33)
    uglifier (1.2.7)
      execjs (>= 0.3.0)
      multi_json (~> 1.3)
    unicorn (4.3.1)
      kgio (~> 2.6)
      rack
      raindrops (~> 0.7)
    uuidtools (2.1.3)
    warden (1.2.1)
      rack (>= 1.0)
    webmock (1.8.9)
      addressable (>= 2.2.7)
      crack (>= 0.1.7)
    xml-simple (1.1.1)
    xpath (0.1.4)
      nokogiri (~> 1.3)
    yajl-ruby (1.1.0)

PLATFORMS
  ruby

DEPENDENCIES
  active_shipping!
  asset_sync
  awesome_print
  aws-s3
  aws-sdk (~> 1.3.4)
  bson_ext (~> 1.5)
  cancan
  capybara
  coffee-rails (~> 3.2.1)
  compass-rails
  dalli
  database_cleaner
  delayed_job_mongoid
  devise (~> 2.1.0)
  devise-encryptable
  exception_notification
  execjs
  factory_girl_rails
  faker
  growl
  guard
  guard-bundler
  guard-coffeescript
  guard-rails-assets
  guard-rspec
  haml (~> 3.1.4)
  haml_coffee_assets
  jbuilder
  jquery-rails
  mail_view!
  money
  mongoid (~> 3.0)
  mongoid-paperclip
  mongoid_search
  mongoid_slug!
  mongoid_token
  newrelic_rpm
  omniauth-facebook
  paperclip!
  paypal_adaptive (~> 0.3.0)
  powder
  pusher
  rack-rewrite
  rails (= 3.2.2)
  rails-backbone
  rb-fsevent
  remotipart
  roadie
  rr
  rspec-rails (~> 2.9.0)
  sass-rails (~> 3.2.3)
  shoulda-matchers
  simple_form
  simplecov
  state_machine
  uglifier (>= 1.0.3)
  unicorn
  webmock
  yajl-ruby

Mongoid Slug seems to creating the :_slug attribute on the model:


.9.3p125 :029 >   ap Member.last
#<Member:0x007ffd448e1590> {
                             :_id => "5045a65a6245b44b77000010",
                       :_slugs => [ [0] "username4" ],
                  :username => "username4"
}

Do you know what I'm doing wrong? Thank you!

thetron commented 12 years ago

I think this is something that is just broken on the current version on git, but from the looks of things from my Mongoid 3 app, mongoid-slug appears to be storing the full slug history by default now, but has no convenience methods for looking up slugs. You can drop a pretty simple class method into your model, like:

def self.find_by_slug(slug)
    self.find_by(:_slugs => slug)
end

Which seems to be doing the trick, for now. Would love to know if this method is missing by design now, or not?

calicoder commented 12 years ago

I tried adding that to my model and it doesn't fix the error when saving the model with an updated slugged field:

>> m = Member.last
>> m.username = "badninja"
>> m.save
NoMethodError: undefined method `username' for "badninja":String
    from /Users/andy/workspace/myapp/app/models/member.rb:51:in `block in <class:Member>'
    from /Users/andy/.rvm/gems/ruby-1.9.3-p125@myapp/bundler/gems/mongoid-slug-0294c663c42b/lib/mongoid/slug.rb:111:in `call'
    from /Users/andy/.rvm/gems/ruby-1.9.3-p125@myapp/bundler/gems/mongoid-slug-0294c663c42b/lib/mongoid/slug.rb:111:in `find_unique_slug_for'
    from /Users/andy/.rvm/gems/ruby-1.9.3-p125@myapp/bundler/gems/mongoid-slug-0294c663c42b/lib/mongoid/slug.rb:272:in `find_unique_slug_for'
    from /Users/andy/.rvm/gems/ruby-1.9.3-p125@myapp/bundler/gems/mongoid-slug-0294c663c42b/lib/mongoid/slug.rb:303:in `find_unique_slug'
    from /Users/andy/.rvm/gems/ruby-1.9.3-p125@myapp/bundler/gems/mongoid-slug-0294c663c42b/lib/mongoid/slug.rb:256:in `build_slug'

I fixed my issue temporarily by adding the following instance method to the model. This is not ideal because I have to add to this every slugged model until the fix is released (assuming that this is a gem problem, not user error):

  def slug
    self._slugs.last
  end

This fixes my problem.

>> m = Member.first
>> m.username = "karina"
 => "karina" 
>> m.save
 => true 
>> m.slug
 => "karina" 
>> m._slugs
 => ["username1", "karina"] 

I would love to know what the bigger issue is here though.  Thanks!
digitalplaywright commented 12 years ago

@calicoder @thetron Same as before there is no slug history by default. However, all slugs are stored in a single variable '_slugs' of Array type both when you are using the slug history and not. The '_slugs' field is indexed.

On master documents can be found by slug using the find(method). For instance, to find a document with the slug 'thetron' type Book.find('thetron').

@thetron I have to look into the last issue later since I am on vacation. The code looks fine at first glance.

palodelincak commented 12 years ago

Same problem here.

I'm using slug without history:

slug :name

Problem:

c = Category.new
c.name = "Test 1"
c.save
c.name = "Test 2"
c.save

#<Category _id: 504f252fc18564a702000001, _type: "category", created_at: 2012-09-11 11:49:24 UTC, updated_at: 2012-09-11 11:49:29 UTC, _slugs: ["test-1", "test-2"], parent_id: nil, parent_ids: [], position: 2, name: "Test 2", code: nil, source_id: nil, hidden: false, product_ids: []>

Category.find("test-1") => true
Category.find("test-2") => true
tomaswitek commented 12 years ago

Hi Guys. Try my fork: https://github.com/tomaswitek/mongoid-slug

digitalplaywright commented 12 years ago

@tomaswitek Thank you for your fixes. I have merged them with master.

@calicoder @thetron @palodelincak Any slugged model now responds to the 'slug' method. The slug method returns the latest slug.

digitalplaywright commented 12 years ago

@thetron After merging @tomaswitek changes slug history is now disabled by default, and only enabled when the history flag is provided. Thank you for reporting this bug.