האם ניתן לסריאל את הבקר?

סיכום מבוסס בינה מלאכותית

In a Dev category discussion titled “Can you serialize a controller?”, mqmenchaca asks whether it’s possible to serialize a Rails controller (specifically EmailController) to return JSON instead of rendering a view, particularly for an unsubscribe endpoint used by an external server. They propose two approaches: defining a custom serializer for the controller or manually rendering JSON using instance variables. While the second approach works, they wonder if the first is viable. pfaffman initially suggests using add_to_serializer, but mqmenchaca clarifies they need to create a new serializer, not extend an existing one. pfaffman then advises creating a new Rails model and Ember route, referencing plugins like Subscriptions and suggesting searching all-the-plugins for route examples. mqmenchaca notes their use case doesn’t require Ember since users won’t interact with the Discourse frontend, which pfaffman confirms simplifies the task — only a route, controller, and model need to be created, avoiding Ember’s complexity. The thread ends with mqmenchaca leaning toward the manual JSON rendering approach for now, while considering whether a full new endpoint is necessary.

Hi Discourse community. I didn’t find a similar topic so I thought I’d start one.

I’m using a plugin to extend Discourse functionality for my organization’s purposes. One of these is rendering a JSON from email/unsubscribe/{KEY}, as we’d like to control these options from a different server than the one we run our Discourse instance. That endpoint is under the purview of the EmailController, and by default the EmailControllerHelper sets instance variables for the controller before rendering a view. Instead, I’d like to return the EmailController as a JSON.

So my question at base is, is it possible to serialize a controller? i.e., can I define a serializer for the controller like this:

  class ::EmailController
    # THE FILE THIS MODIFIES: app/controllers/email_controller.rb
    # Return a json

    module ReturnAsJSON
      def unsubscribe
        super

        render EmailUnsubscribeSerializer.new(self, root: false).to_json
      end
    end

    prepend ReturnAsJSON
  end

  class EmailUnsubscribeSerializer < ApplicationSerializer
    attributes :topic, :type, :unsubscribed_from_all, :user

    def user
      BasicUserSerializer.new(object.user, root: false).as_json
    end
  end

or am I better off brute forcing this?

  class ::EmailController
    # THE FILE THIS MODIFIES: app/controllers/email_controller.rb
    # Return a json

    module ReturnAsJSON
      def unsubscribe
        super

        render json: {type: @type, unsubscribed_from_all: @unsubscribed_from_all, etc.}
      end
    end

    prepend ReturnAsJSON
  end

The 2nd approach looks like it works, so if the 1st approach doesn’t at least I have a decent workaround.

Search existing plugins or discourse source for add_to_serializer.

Thanks @pfaffman , but I don’t think that’s what I’m looking for. I tried that route for a while, (and actually use it else where in our custom plugin), but I don’t know if it will help here.. As far as I can tell, NO controlller in the Discourse repo is serialized. I’m not trying to ADD to an existing serializer, I’m trying to CREATE a new one.

Ah. Then you need to add a Rails model and then also add a model to Ember. I have done it several times and still find it very confusing.

Check out an other plugin that adds a route. Subscriptions is one, but you might also get GitHub - discourse/all-the-plugins · GitHub and then do a find for “route*”. The Rails part is in config and the Ember part is in assets/javascripts/discourse/routes.

Great, thanks. I might be able to get away with not using Ember, as our users aren’t meant to see the Discourse frontend at all.

I have done it several times and still find it very confusing.

This is some comfort here. I’ll maybe opt for my 2nd route above and assess whether a new endpoint is needed here. Thanks!

That makes it much easier (for me, especially). So after you add the route you pull /your-new-route.json and that should do the trick and then you can avoid the other 3-5 files (or is it 500?) that you have to create in Ember.

So you add the route and then add the controller and the model. I think it’s just those 3 files that you have to create.