# Getting the NoMethodError error when editing the topic due to my plugin

**URL:** https://meta.discourse.org/t/getting-the-nomethoderror-error-when-editing-the-topic-due-to-my-plugin/59471
**Category:** Development
**Created:** [19 Marzo 2017, 7:55am UTC](https://meta.discourse.org/t/getting-the-nomethoderror-error-when-editing-the-topic-due-to-my-plugin/59471 "2017-03-19T07:55:58Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![net\_deamon](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/net_deamon/32/70126_2.png) [@net\_deamon](https://meta.discourse.org/u/net_deamon)
#### Post date: [19 Marzo 2017, 7:55am UTC](https://meta.discourse.org/t/getting-the-nomethoderror-error-when-editing-the-topic-due-to-my-plugin/59471/1 "2017-03-19T07:55:58Z")

</div>

Hi I am getting following error when trying to update ( edit ) the post

**Error Info**

```
NoMethodError - undefined method `call' for nil:NilClass
Did you mean? caller:
  lib/post_revisor.rb:335:in `block (2 levels) in update_topic'
  lib/post_revisor.rb:333:in `block in update_topic'
  activerecord (4.2.7.1) lib/active_record/connection_adapters/abstract/database_statements.rb:211:in `transaction'
  activerecord (4.2.7.1) lib/active_record/transactions.rb:220:in `transaction'
  lib/post_revisor.rb:332:in `update_topic'
  lib/post_revisor.rb:242:in `revise'
  lib/post_revisor.rb:204:in `revise_post'
  lib/post_revisor.rb:152:in `block in revise!'
  activerecord (4.2.7.1) lib/active_record/connection_adapters/abstract/database_statements.rb:213:in `block in transaction'
  activerecord (4.2.7.1) lib/active_record/connection_adapters/abstract/transaction.rb:184:in `within_new_transaction'
  activerecord (4.2.7.1) lib/active_record/connection_adapters/abstract/database_statements.rb:213:in `transaction'
  activerecord (4.2.7.1) lib/active_record/transactions.rb:220:in `transaction'
  lib/post_revisor.rb:151:in `revise!'
  app/controllers/topics_controller.rb:243:in `update'
  actionpack (4.2.7.1) lib/action_controller/metal/implicit_render.rb:4:in `send_action'
  actionpack (4.2.7.1) lib/abstract_controller/base.rb:198:in `process_action'
  actionpack (4.2.7.1) lib/action_controller/metal/rendering.rb:10:in `process_action'
  actionpack (4.2.7.1) lib/abstract_controller/callbacks.rb:20:in `block in process_action'
  activesupport (4.2.7.1) lib/active_support/callbacks.rb:117:in `call'
  activesupport (4.2.7.1) lib/active_support/callbacks.rb:555:in `block (2 levels) in compile'
  activesupport (4.2.7.1) lib/active_support/callbacks.rb:505:in `call'
  activesupport (4.2.7.1) lib/active_support/callbacks.rb:92:in ` __run_callbacks__'
  activesupport (4.2.7.1) lib/active_support/callbacks.rb:778:in `_run_process_action_callbacks'
  activesupport (4.2.7.1) lib/active_support/callbacks.rb:81:in `run_callbacks'
  actionpack (4.2.7.1) lib/abstract_controller/callbacks.rb:19:in `process_action'
  actionpack (4.2.7.1) lib/action_controller/metal/rescue.rb:29:in `process_action'
  actionpack (4.2.7.1) lib/action_controller/metal/instrumentation.rb:32:in `block in process_action'
  activesupport (4.2.7.1) lib/active_support/notifications.rb:164:in `block in instrument'
  activesupport (4.2.7.1) lib/active_support/notifications/instrumenter.rb:20:in `instrument'
  activesupport (4.2.7.1) lib/active_support/notifications.rb:164:in `instrument'
  actionpack (4.2.7.1) lib/action_controller/metal/instrumentation.rb:30:in `process_action'
  actionpack (4.2.7.1) lib/action_controller/metal/params_wrapper.rb:250:in `process_action'
  activerecord (4.2.7.1) lib/active_record/railties/controller_runtime.rb:18:in `process_action'
  actionpack (4.2.7.1) lib/abstract_controller/base.rb:137:in `process'
  actionview (4.2.7.1) lib/action_view/rendering.rb:30:in `process'
  rack-mini-profiler (0.10.1) lib/mini_profiler/profiling_methods.rb:102:in `block in profile_method'
  actionpack (4.2.7.1) lib/action_controller/metal.rb:196:in `dispatch'
  actionpack (4.2.7.1) lib/action_controller/metal/rack_delegation.rb:13:in `dispatch'
  actionpack (4.2.7.1) lib/action_controller/metal.rb:237:in `block in action'
  actionpack (4.2.7.1) lib/action_dispatch/routing/route_set.rb:74:in `dispatch'
  actionpack (4.2.7.1) lib/action_dispatch/routing/route_set.rb:43:in `serve'
  actionpack (4.2.7.1) lib/action_dispatch/journey/router.rb:43:in `block in serve'
  actionpack (4.2.7.1) lib/action_dispatch/journey/router.rb:30:in `serve'
  actionpack (4.2.7.1) lib/action_dispatch/routing/route_set.rb:817:in `call'
  rack-protection (1.5.3) lib/rack/protection/frame_options.rb:31:in `call'
  omniauth (1.3.1) lib/omniauth/strategy.rb:186:in `call!'
  omniauth (1.3.1) lib/omniauth/strategy.rb:164:in `call'
  omniauth (1.3.1) lib/omniauth/strategy.rb:186:in `call!'
  omniauth (1.3.1) lib/omniauth/strategy.rb:164:in `call'
  omniauth (1.3.1) lib/omniauth/strategy.rb:186:in `call!'
  omniauth (1.3.1) lib/omniauth/strategy.rb:164:in `call'
  omniauth (1.3.1) lib/omniauth/strategy.rb:186:in `call!'
  omniauth (1.3.1) lib/omniauth/strategy.rb:164:in `call'
  omniauth (1.3.1) lib/omniauth/strategy.rb:186:in `call!'
  omniauth (1.3.1) lib/omniauth/strategy.rb:164:in `call'
  omniauth (1.3.1) lib/omniauth/strategy.rb:186:in `call!'
  omniauth (1.3.1) lib/omniauth/strategy.rb:164:in `call'
  omniauth (1.3.1) lib/omniauth/builder.rb:63:in `call'
  rack (1.6.5) lib/rack/conditionalget.rb:38:in `call'
  rack (1.6.5) lib/rack/head.rb:13:in `call'
  actionpack (4.2.7.1) lib/action_dispatch/middleware/params_parser.rb:27:in `call'
  actionpack (4.2.7.1) lib/action_dispatch/middleware/flash.rb:260:in `call'
  rack (1.6.5) lib/rack/session/abstract/id.rb:225:in `context'
  rack (1.6.5) lib/rack/session/abstract/id.rb:220:in `call'
  actionpack (4.2.7.1) lib/action_dispatch/middleware/cookies.rb:560:in `call'
  activerecord (4.2.7.1) lib/active_record/query_cache.rb:36:in `call'
  activerecord (4.2.7.1) lib/active_record/connection_adapters/abstract/connection_pool.rb:653:in `call'
  activerecord (4.2.7.1) lib/active_record/migration.rb:377:in `call'
  actionpack (4.2.7.1) lib/action_dispatch/middleware/callbacks.rb:29:in `block in call'
  activesupport (4.2.7.1) lib/active_support/callbacks.rb:88:in ` __run_callbacks__'
  activesupport (4.2.7.1) lib/active_support/callbacks.rb:778:in `_run_call_callbacks'
  activesupport (4.2.7.1) lib/active_support/callbacks.rb:81:in `run_callbacks'
  actionpack (4.2.7.1) lib/action_dispatch/middleware/callbacks.rb:27:in `call'
  actionpack (4.2.7.1) lib/action_dispatch/middleware/reloader.rb:73:in `call'
  actionpack (4.2.7.1) lib/action_dispatch/middleware/remote_ip.rb:78:in `call'
  better_errors (2.1.1) lib/better_errors/middleware.rb:84:in `protected_app_call'
  better_errors (2.1.1) lib/better_errors/middleware.rb:79:in `better_errors_call'
  better_errors (2.1.1) lib/better_errors/middleware.rb:57:in `call'
  actionpack (4.2.7.1) lib/action_dispatch/middleware/debug_exceptions.rb:17:in `call'
  actionpack (4.2.7.1) lib/action_dispatch/middleware/show_exceptions.rb:30:in `call'
  logster (1.2.7) lib/logster/middleware/reporter.rb:31:in `call'
  railties (4.2.7.1) lib/rails/rack/logger.rb:38:in `call_app'
  railties (4.2.7.1) lib/rails/rack/logger.rb:22:in `call'
  config/initializers/100-quiet_logger.rb:17:in `call_with_quiet_assets'
  config/initializers/100-silence_logger.rb:29:in `call'
  actionpack (4.2.7.1) lib/action_dispatch/middleware/request_id.rb:21:in `call'
  rack (1.6.5) lib/rack/methodoverride.rb:22:in `call'
  rack (1.6.5) lib/rack/runtime.rb:18:in `call'
  actionpack (4.2.7.1) lib/action_dispatch/middleware/static.rb:120:in `call'
  rack (1.6.5) lib/rack/sendfile.rb:113:in `call'
  lib/middleware/missing_avatars.rb:21:in `call'
  lib/middleware/turbo_dev.rb:33:in `call'
  rack-mini-profiler (0.10.1) lib/mini_profiler/profiler.rb:278:in `call'
  message_bus (2.0.2) lib/message_bus/rack/middleware.rb:62:in `call'
  railties (4.2.7.1) lib/rails/engine.rb:518:in `call'
  railties (4.2.7.1) lib/rails/application.rb:165:in `call'
  railties (4.2.7.1) lib/rails/railtie.rb:194:in `method_missing'
  rack (1.6.5) lib/rack/urlmap.rb:66:in `block in call'
  rack (1.6.5) lib/rack/urlmap.rb:50:in `call'
  rack (1.6.5) lib/rack/content_length.rb:15:in `call'
  puma (3.6.0) lib/puma/configuration.rb:225:in `call'
  puma (3.6.0) lib/puma/server.rb:578:in `handle_request'
  puma (3.6.0) lib/puma/server.rb:415:in `process_client'
  puma (3.6.0) lib/puma/server.rb:275:in `block in run'
  puma (3.6.0) lib/puma/thread_pool.rb:116:in `block in spawn_thread'

```

**When I tried running discourse in safe-mode, with no unofficial plugins, I didnt get the error**

In my plugin, I am saving the custom field to the discourse topic when it is created  
I am able to save save the custom field, but I am not able to figure out why it is throwing above error when editing the topic. Am I missing something, do I have to handle edit scenarios?

**\> I am also changing the category of the topic based on post, can this break the edit functionality?**

```
Topic.register_custom_field_type('test', :text)
PostRevisor.track_topic_field(:testid) 
DiscourseEvent.on(:topic_created) do | topic, params, user |
    testid = params[:testid].to_s
    topic.custom_fields['test'] = testid;
    category_id = 1 # Set it to undefined category
   
    # I also change the category of the topic here, after finding the category based on the testid

    @category = Category.find_by(name: testid)
   
    if @category then  
      category_id = @category[:id];
      puts "category does exits"
    else
      puts "category does not exits"
      @category = Category.create({"name"=>testid, "color"=>"AB9364", "text_color"=>"FFFFFF", "parent_category_id"=>"", "slug"=>"", "allow_badges"=>"true", "sort_order"=>"", "topic_featured_link_allowed"=>"true", "default_view"=>"latest", "permissions"=>{"everyone"=>1}}.merge(user: user))
      if @category.save
        category_id = @category[:id];  
      end
    end
   topic[:category_id] = category_id;
  topic.save
end

add_to_serializer :topic_view_ , :test do
    object.topic.custom_fields['test']  
end

add_to_serializer :topic_list_item_ , :test do
    object.custom_fields['test']  
end

```

I was also going through discourse-tagging plugin, and here they are checking if the tags are present or not. Do I have to do something similar?

> <https://github.com/discourse/discourse-tagging/blob/master/plugin.rb#L388>

---

<div class="post-metadata">

### Author: ![gdpelican](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/gdpelican/32/81308_2.png) [@gdpelican](https://meta.discourse.org/u/gdpelican)
#### Post date: [19 Marzo 2017, 10:56am UTC](https://meta.discourse.org/t/getting-the-nomethoderror-error-when-editing-the-topic-due-to-my-plugin/59471/2 "2017-03-19T10:56:51Z")

</div>

`track_topic_field` is expecting a block to execute when the tracked field is changed, so the following line:

```plaintext
PostRevisor.track_topic_field(:testid)

```

Will break the thing, whereas

```plaintext
PostRevisor.track_topic_field(:testid) { |tc| puts "Hello world!" }

```

will work (and, I reckon, print ‘Hello world!’ to the console when you change the value of ‘testid’ on a topic)

I don’t get what the intended functionality is here, so can’t offer further advice, but if you’re tracking a topic field you also need to provide _what to do_ once that field has changed.

---

<div class="post-metadata">

### Author: ![net\_deamon](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/net_deamon/32/70126_2.png) [@net\_deamon](https://meta.discourse.org/u/net_deamon)
#### Post date: [19 Marzo 2017, 11:14am UTC](https://meta.discourse.org/t/getting-the-nomethoderror-error-when-editing-the-topic-due-to-my-plugin/59471/3 "2017-03-19T11:14:11Z")

</div>

EDIT

Thanks, I tried the above code , and it worked.  
Thankyou

I was trying something on similar lines

Here they watch the topic\_guuid

> <https://github.com/cos-archives/discourse-osf-projects/blob/master/plugin.rb#L236>

Then they get that value in before\_create\_topic event

> <https://github.com/cos-archives/discourse-osf-projects/blob/master/plugin.rb#L250>

I am able to save the custom model to topic, but when I try to edit the first post of topic, it throws error.  
If I comment out the PostRevisor code, the error dosent come. So I think it is due to PostRevisor only.

> [@gdpelican](#):
>
> if you’re tracking a topic field you also need to provide what to do once that field has changed.

I do not have to do anything if value changes, I just need to get the value from UI and use it in plugin.rb to save it to topic. And it throws only in when editing the first post of topic. In the postrevisor class, I kept breakpoint to see

```
def update_topic
    Topic.transaction do
      PostRevisor.tracked_topic_fields.each do |f, cb|

        if !@topic_changes.errored? && @fields.has_key?(f)
          cb.call(@topic_changes, @fields[f])
        end
      end

      unless @topic_changes.errored?
        @topic_changes.check_result(@topic.save(validate: @validate_topic))
      end
    end
  end

```

Here in the PostRevisor.tracked\_topic\_fields array, the value for testid is “nil”.  
Here is the snippet. When it comes to testid, it throws error

`{:title=>#<Proc:0x007f8e5e3f9258@/Users/santosh/discourse/lib/post_revisor.rb:65>, :category_id=>#<Proc:0x007f8e5ad8b130@/Users/santosh/discourse/lib/post_revisor.rb:70>, :tags=>#<Proc:0x007f8e5ad8a438@/Users/santosh/discourse/lib/post_revisor.rb:75>, :tags_empty_array=>#<Proc:0x007f8e5ad8a348@/Users/santosh/discourse/lib/post_revisor.rb:87>, :featured_link=>#<Proc:0x007f8e5ad895b0@/Users/santosh/discourse/lib/post_revisor.rb:98>, :testid=>nil}`

---

<div class="post-metadata">

### Author: ![gdpelican](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/gdpelican/32/81308_2.png) [@gdpelican](https://meta.discourse.org/u/gdpelican)
#### Post date: [19 Marzo 2017, 11:26am UTC](https://meta.discourse.org/t/getting-the-nomethoderror-error-when-editing-the-topic-due-to-my-plugin/59471/4 "2017-03-19T11:26:13Z")

</div>

I’m sensing a misunderstanding here. The definition for `PostRevisor.track_topic_field` is essentially

```ruby
def self.track_topic_field(field, &block)
  tracked_topic_fields[field] = block # store this block for later
end

```

Then, later on once the topic has changed:

```ruby
# key here is the name of the field, and value is the block we stored
# (key, value is called f, cb in the code; we're iterating over a Hash)
tracked_topic_fields.each do |key, value|
  value.call() # call the block we passed earlier. If this is nil, it will blow up
end

```

So… if you don’t pass a block to `track_topic_field`, it’s going to go badly when running that `update_topic` code, because it’s expecting a block (technically a Proc, which is an object that always responds to the `call` method) to execute as an update callback.

---

<div class="post-metadata">

### Author: ![net\_deamon](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/net_deamon/32/70126_2.png) [@net\_deamon](https://meta.discourse.org/u/net_deamon)
#### Post date: [19 Marzo 2017, 11:28am UTC](https://meta.discourse.org/t/getting-the-nomethoderror-error-when-editing-the-topic-due-to-my-plugin/59471/5 "2017-03-19T11:28:53Z")

</div>

Thankyou for detailed explanation  
You are correct, passing the block ( even something like logging hello world ), didnt throw the error when updating the topic.
