Was ist dieser add_to_serializer Code in all diesen Plugins

I have seen this code in discourse_signatures plugin

User.register_custom_field_type('see_signatures', :boolean)
User.register_custom_field_type('signature_url', :text)
User.register_custom_field_type('signature_raw', :text)

if SiteSetting.signatures_enabled then
  add_to_serializer(:post, :user_signature, false) {
    if SiteSetting.signatures_advanced_mode then
      object.user.custom_fields['signature_raw']
    else
      object.user.custom_fields['signature_url']
    end
  }

  # I guess this should be the default @ discourse. PR maybe?
  add_to_serializer(:user, :custom_fields, false) {
    if object.custom_fields == nil then
      {}
    else
      object.custom_fields
    end
  }
end

In discourse national flags plugin

User.register_custom_field_type('nationalflag_iso', :text)

if SiteSetting.nationalflag_enabled then
  byebug;
  add_to_serializer(:post, :user_signature, false) {
    object.user.custom_fields['nationalflag_iso']
  }
  byebug;
  # I guess this should be the default @ discourse. PR maybe?
  add_to_serializer(:user, :custom_fields, false) {
    if object.custom_fields == nil then
      {}
    else
      object.custom_fields
    end
  }
end

I am not able to understand what is add_to_serializer is doing.

I checked in def add_to_serializer

def add_to_serializer(serializer, attr, define_include_method=true, &block)
  klass = "#{serializer.to_s.classify}Serializer".constantize rescue "#{serializer.to_s}Serializer".constantize

  klass.attributes(attr) unless attr.to_s.start_with?("include_")

  klass.send(:define_method, attr, &block)

  return unless define_include_method

  # Don't include serialized methods if the plugin is disabled
  plugin = self
  klass.send(:define_method, "include_#{attr}?") { plugin.enabled? }
end

I understand that User.register_custom_field_type('signature_raw', :text) will register a custom field type to User object. But what is add_to_serializer doing? I am not able to understand, can you explain me in plain english?

2 „Gefällt mir“

It’s essentially adding to the information that Discourse serializes out when sending that model to the client. For example, you may see a request to this endpoint when loading up a topic page:

http://meta.discourse.org/t/2349082394.json

which returns some payload like this:

{
  title: "Some topic title",
  archetype: 'regular',
  category_id: 7,
  post_stream: { posts: [...] },
  posts_count: 15,
  (etc etc.. lots more info about the topic in question)
}

Which is the json representation of a Discourse topic.

If I want to know more about the topic because of additional ‘stuff’ I do in my plugin, I can put in a line like

add_to_serializer :topic, :flag_name do
  object.flag_name # <- NB that 'object' here is the topic being serialized
end

(Also, by default, this method simply sends the specified message to ‘object’, meaning that

add_to_serializer :topic, :flag_name

is the same as

add_to_serializer :topic, :flag_name do
  object.flag_name
end

)

Once I’ve added the method to the serializer, I can end up with JSON output which includes that additional info

{
  title: "Some topic title",
  archetype: 'regular',
  category_id: 7,
  post_stream: { posts: [...] },
  posts_count: 15,
  flag_name: "some flag name"
  ...
}

Also note that you could achieve the same thing by overwriting the TopicSerializer class (which is exactly what the code snippet you’ve provided is doing)

# plugin.rb
TopicSerializer.class_eval do
  attributes :flag_name
  def flag_name
    object.flag_name
  end
end
20 „Gefällt mir“

Hi,
When running the following code,

TopicSerializer.class_eval do
  attributes :flag_name
  def flag_name
    object.flag_name
  end
end

I was getting the error “block in activate!’: uninitialized constant TopicSerializer (NameError)”. I think I have to “import” or “require” the TopicSerializer dependency. Can you please tell me what would be the dependency, as I am not able to figure it out.

1 „Gefällt mir“

Add this directly above your code require_dependency 'topic_serializer'

require_dependency 'topic_serializer'
class ::TopicSerializer
  attributes :flag_name
  def flag_name
    object.flag_name
  end
end
1 „Gefällt mir“

Hi thanks, but I got the error " `load’: No such file to load – topic_serializer (LoadError)". Does it pull from the app/serializers folder? I checked in that folder, I could find topic_list_serializer.rb, and many other related to topic, but couldnt find topic_serializer.rb

1 „Gefällt mir“

Right! Try TopicViewSerializer.

require_dependency 'topic_view_serializer'
class ::TopicViewSerializer
  attributes :flag_name
  def flag_name
    object.flag_name
  end
end
5 „Gefällt mir“

Heyy, I have added a custom field to my category edit box.

When I submit the form, I can see something these fields are submitted in the js console
custom_fields[default_tag][]:good-feedback custom_fields[default_tag][]:one-more-tag

in my main plugin file, I am doing

add_to_serializer(:basic_category, :default_tag){object.custom_fields[“default_tag”]}

My custom fields aren’t getting saved to the db.

does doing:

add_to_serializer(:basic_category, :default_tag, false ){object.custom_fields[“default_tag”]}

now work?

I had solved it that time by adding a function on :before_action event and converted the array to a delimited string and vice versa while retrieving.

I didn’t actually dig into why an array couldn’t be stored as custom field out of the box.

1 „Gefällt mir“

So this might streamline the code potentially?

Yes it would if it worked in this case. I’ll try this in sometime and get back to you.

1 „Gefällt mir“

Poor you that must’ve been painful at the time :wink:

1 „Gefällt mir“

It was a sunday evening and curiosity took over. It was somewhat painful but fun.
It was something that @pfaffman was trying to do.

No pain no gain :wink:

1 „Gefällt mir“

haha, so true! …

1 „Gefällt mir“

Hallo, ich habe das gleiche Problem (custom_fields werden in der JS-Konsole übermittelt, aber nicht in der Datenbank gespeichert). Ich habe in meiner Haupt-Plugin-Datei die Methode add_to_serializer(:basic_category, :default_tag, false ){object.custom_fields["default_tag"]} verwendet.

Würdest du diese Lösung immer noch empfehlen?

1 „Gefällt mir“

Hier tauchen viele Fragen auf. Welche benutzerdefinierten Felder sind vorrangig gemeint?

Ich arbeite an einem Plugin, um die Synchronisierung von Discourse-Gruppen mit LDAP zu automatisieren. Ich habe ein benutzerdefiniertes Feld namens ldap_dn zur Gruppe hinzugefügt, um den LDAP-Gruppennamen darin zu speichern. Ich versuche, den Wert des benutzerdefinierten Felds aus einem Eingabefeld abzurufen, das ich im membership-plugin-outlet hinzugefügt habe, und diesen dann in der Datenbank zu speichern, um ihn später zu verwenden.

Dafür habe ich Folgendes in meine plugin.rb-Datei aufgenommen:

Group.register_custom_field_type('ldap_dn', :text)
Group.preload_custom_fields << "ldap_dn" if Group.respond_to?(:preloaded_custom_fields)

if SiteSetting.groups_sync_enabled
add_to_serializer(:group_show, :custom_fields, false) { object.custom_fields }
end

Ich bin neu in Rails und Ember und bin mir nicht sicher, ob es noch einen weiteren Schritt gibt, den ich durchführen muss, um die benutzerdefinierten Felder in der Datenbank zu speichern, oder wo das Problem liegt.

1 „Gefällt mir“

Ich denke, wenn du
`register_editable_group_custom_field ‘field_name’
zu deiner plugin.rb hinzufügst,

sollte das den Job erledigen.

Hinweis:
Der Serializer wird verwendet, um Daten an den Client zu senden, nicht um sie zu empfangen.

1 „Gefällt mir“

Ahh, okay! Ich bin noch neu hier, also ist das vielleicht eine ziemlich offensichtliche Frage, aber um die Daten zu erhalten, mache ich das über die API, oder?

1 „Gefällt mir“

Meine Lösung gibt deinem Feld ein grünes Signal, sobald die Daten auf dem Server ankommen. Es geht also um den Empfang der Daten.

1 „Gefällt mir“