Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide succinct example of extending models in Readme or Wiki #65

Closed
equivalentideas opened this issue Apr 26, 2019 · 7 comments
Closed

Comments

@equivalentideas
Copy link

Monkey patching / extending models seems to be a bit tricky in Rails, though I'm sure there's a conventional approach you might recommend for the Gutentag models.

I'm trying to override #to_params on Gutentag::Tag in an initializer, but I believe it's being canceled by Rails's loading process, and I'm going to hack around it for now as I can't work it out.

I understand solving that problem isn't within the scope of this project, but I thought that a simple example of the conventional pattern for extending the models might be a good addition to the readme or wiki here, as it seems like a potentially common use case.

@pat
Copy link
Owner

pat commented Apr 28, 2019

Hi Luke,

It is a bit of an edge case, but would nice to have it noted somewhere. Did you end up figuring out a neat solution? I'm wondering if the best way is to include a module into Gutentag::Tag within an after_initialize block…

# in config/initializers/gutentag.rb or similar

Rails.application.config.after_initialize do
  Gutentag::Tag.include TagParams
end

@equivalentideas
Copy link
Author

equivalentideas commented Apr 29, 2019

Hey Pat, yep I did just get it working to extract a couple of methods (your after_initialize tip here was the key 😄 ):

# in config/initializers/gutentag.rb

Rails.application.config.after_initialize do
  Gutentag::Tag.instance_eval do
    def find_by_name_param!(string)
      self.find_by_name!(string.tr('+', ' '))
    end
  end

  Gutentag::Tag.class_eval do
    def to_param
      self.name.tr(' ', '+')
    end
  end
end

Do you think that would be useful as an example of extending the classes? You might prefer the module inclusion, which seems cleaner maybe.

@equivalentideas
Copy link
Author

equivalentideas commented Apr 30, 2019

Turned out that wasn't a working solution because in dev, rails reloads the models between page loads and blows away our changes :) Here's what I have working now:

# in config/initializers/gutentag.rb

require 'tag'

Rails.application.config.to_prepare do
  Gutentag::Tag.include Tag
end

And

# in lib/tag.rb

module Tag
  def self.included base
    base.extend ClassMethods
    base.send :include, InstanceMethods
  end

  module ClassMethods
    def find_by_name_param!(string)
      self.find_by_name!(string.tr('+', ' '))
    end
  end

  module InstanceMethods
    def to_param
      self.name.tr(' ', '+')
    end
  end
end

pat added a commit that referenced this issue May 3, 2019
@pat
Copy link
Owner

pat commented May 3, 2019

This is now in the README :) https://github.com/pat/gutentag#extending

@pat pat closed this as completed May 3, 2019
@equivalentideas
Copy link
Author

Very nice :) Thanks @pat 💞 this has been really useful for a project I'm working on, tracking the public lobbying activities of the fossil fuels lobby.

@pat
Copy link
Owner

pat commented May 3, 2019

Oh interesting! Is that deployed publicly anywhere?

@equivalentideas
Copy link
Author

Oh interesting! Is that deployed publicly anywhere?

Not yet, but I'll let you know :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants