Custom Field not working


(KLm) #1

Hi All,

I am fairly new to discourse and I am attempting to add a customs field but I am not able to,

Could someone please help me.

My code

after_initialize do

  module ::Foo
  	 PLUGIN_NAME ||= -"discourse-myapi"
     STORE_NAME ||= "replies".freeze

    class Engine < ::Rails::Engine
      engine_name PLUGIN_NAME
      isolate_namespace Foo

    end
  end

  require_dependency "application_controller"


  class Foo::Example
  	class << self

        def bump(id)
           cf_time = Time.zone.now 	
          DistributedMutex.synchronize("#{Foo::PLUGIN_NAME}-#{cf_time.iso8601}") do
          	user = User.find(id)
            user.custom_fields['signature_url'] = cf_time
            user.save!
            return user
          end
        end

  	end	
  end

  class Foo::BarController < ::ApplicationController

  	requires_plugin Foo::PLUGIN_NAME

    def custom_field_test
      begin
        user = Foo::Example.bump(1)
        render json: { user: user }
      rescue StandardError => e
        render_json_error e.message
      end
    end

  end

  Foo::Engine.routes.draw do'
    get  '/custom_field_test' => 'bar#custom_field_test'
  end

  Discourse::Application.routes.append do
    mount ::Foo::Engine, at: '/myapiclass'
  end


end

Thanks


(KLm) #2

I am going to answer my own question here, since I kind of understand where I was making mistake in terms of my thinking process, and also a benefit of getting feedback from the rest of the team here, as well as for the benefit of new comers to custom_fields functionality in Discourse.

Basically I was making a mistake in thinking without investigation that after I create a custom field on User object by doing

user = User.find(1)
user.custom_fields[“test_field”] = " X X X X"
user.save

I was expecting the custom field to be created on the user object i.e. to become

custome_field_test_field

and I was doing:

user.custom_fields_test_field

But after investigating deeply, I found out that, custom_field is actually an object

user.custom_fields[“test_field”] = { }

and when I do

user.custom_fields[“test_field”] = " X X X X"

it appends it to the hash/object

Therefore it becomes

user.custom_fields = {
"test_field"] = " X X X X"
}


(Jay Pfaffman) #3

You also want to add a name to your custom field. The importers all use custom fields, so you could look there for examples.


(KLm) #4

Hi @pfaffman

Thanks for feedback, but I am not sure if I am following it, could you please give example.

And also on the rails console if I do

[10] pry(main)&gt; user = **User** .find( **1** )
[11] pry(main)&gt; pp user.custom_fields 

(2.5ms) SELECT "user_custom_fields"."name", "user_custom_fields"."value" FROM "user_custom_fields" WHERE "user_custom_fields"."user_id" = 1 ORDER BY id asc

{"xxxxxxxxxxxxxxxx"=&gt;"2018-06-16 12:23:39 UTC",

 "test_two"=&gt;"1234567",

 "fountain_cake"=&gt;"2018-06-16 13:16:25 UTC"}

=&gt; **{ **"** xxxxxxxxxxxxxxxx **"** =&gt; **"** 2018-06-16 12:23:39 UTC **"** , **"** test_two **"** =&gt; **"** 1234567 **"** , **"** fountain_cake **"** =&gt; **"** 2018-06-16 13:16:25 UTC **"** }**

I can see the custom fields I added,

But on the plugin:

def custom_field_test
  begin
  	 cf_time = Time.zone.now 	
     user = User.find(1)
     user.custom_fields['fountain_cake'] = cf_time
     user.save!
    user_after_update = User.find(1)
    json = serialize_data(user_after_update, UserSerializer, root: false)
    render json: { user: json }
  rescue StandardError => e
    render_json_error e.message
  end
end

It returns the custom_fields as empty object, any thought ?


(Jay Pfaffman) #5

Look in scripts/import_scripts at any importer to see how they create custom fields.


(KLm) #6

@pfaffman thanks for let me know about the necessary of adding importers for custom field I am looking into them,

On the second part of the question, do you know if Redis caches requests, when you call the DB from rails application ? because at the moment I am two distinct results, calling via the controller and directly to the database via rails console.

Thanks


(KLm) #7

Anybody know how I can make the “custom_fields” on User visible ? at the moment when I fetch user object I am getting the custom_fields property is empty object/hash - {}.

But if I do user.custom_fields, I can see all the custom fields, however as part of the User object is empty.

Please refer to the code snippet above for more details.

Thanks


(Vinoth Kannan) #8

For that you have to whitelist those custom fields in either public user custom fields or staff user custom fields site setting according to your need.


(KLm) #9

@vinothkannans Thanks for reply,

I am new to discourse and I am not sure, when you say - public user custom fields - if you are referring to the UI part of discourse, on JS or the actual Ruby code. could you please elaborate, or point me to an example.

Thanks


(Vinoth Kannan) #10

I mean you have to add that custom field’s name in admin site setting at the URL /admin/site_settings/category/all_results?filter=public%20user%20custom%20fields like below


(KLm) #11

@vinothkannansThanks so much,

I can see the field returning as part of the API.

Although I would like to know the wiring under the hood as to why you need to whitelist it ?

Thanks


(Vinoth Kannan) #12

Custom fields may contain sensitive user data. We shouldn’t expose it by default.


(Pooja Patel) #13

is this features work for requirement, I want to see all users in two different categories, “supplier” or “customer”

If i add into customize -> User Fields -> Filed Type -> Dropdown > Add Field Name

Require tick from below two
Options
Supplier
Customer

Can anyone help me for that, Where i can see this report? It is come with > users List


(Jay Pfaffman) #14

You probably need the data Explorer plugin to get a report.


(KLm) #15

@vinothkannans . Thanks for replying.

And I have another question about custom fields, I am not able to see the custom_field on Posts object, nor I can whitelist it on the ui admin page, can you help with this,

Thanks


(Vinoth Kannan) #16

You should manually add it from a plugin using add_to_serializer(:post, ... method.


(KLm) #17

@vinothkannans Thanks for suggestion, and it’s working.

One more thing I would like to ask you is, I am trying to set an object as in a JSON object into the custom field, However, when I se it, is setting it as a string with character escapes, is there a way to handle this.

Thanks


(Vinoth Kannan) #18
JSON.parse(post.custom_fields["FIELD_NAME"])

You can use above command to convert the string to JSON object.


(KLm) #19

Thanks @vinothkannans

Last question, do you know if is possible in Discourse, to intercept a response from POST request, modify the body, e.g. add a custom field before sending to the client ?

Thanks


(Vinoth Kannan) #20

Yes, it’s possible. You should go through to the available methods in plugin/instance.rb file. You can also check existing plugin codes to learn about how they handling different situations. And go through Beginner’s Guide to Creating Discourse Plugins - Part 1.

Edit: You can also monkey patch controller methods.