如何通过模型配置在执行查询后调用自定义Gem的翻译函数?
Got it, let's break down how to implement this so your custom translation gem automatically kicks in after database queries, with per-model control over whether it runs.
1. Hook into ActiveRecord's Query Lifecycle
You'll want to tap into ActiveRecord's callbacks to trigger your translation logic right after a record is loaded from the database. We'll use a concern in your gem to make this reusable across models:
# lib/your_gem/translation_integration.rb module YourGem module TranslationIntegration extend ActiveSupport::Concern included do # Class-level flag to enable/disable your gem's translations class_attribute :custom_translations_enabled, default: false # Trigger translation when a record is found/loaded from DB after_find :apply_custom_translations, if: :custom_translations_enabled? # Handle cases where records are initialized from persisted data (e.g., from a relation) after_initialize :apply_custom_translations, if: -> { custom_translations_enabled? && persisted? } # Class methods to toggle the feature def self.enable_custom_translations self.custom_translations_enabled = true end def self.disable_custom_translations self.custom_translations_enabled = false end end private def apply_custom_translations # Call your gem's universal translation function here # Replace this with your actual implementation that uses Mobility YourGem::Translator.apply_translations(self) end end end
2. Add Per-Model Control
Models can opt-in to your gem's behavior by including the concern and enabling the flag. You can also toggle it dynamically if needed:
# app/models/center.rb class Center < ApplicationRecord include YourGem::TranslationIntegration # Enable your gem's translations globally for this model enable_custom_translations # Optional: If you want per-instance control instead, use an attr_accessor # attr_accessor :use_custom_translations # after_find :apply_custom_translations, if: :use_custom_translations end
3. Use It in Controllers (No Extra Code Needed!)
Now your queries will automatically apply translations without modifying controller logic:
def index @centers = Center.all # Your gem's translate function runs on each record automatically render json: {status: 'success', data: @centers}, status: :ok end def show @center = Center.find(params[:id]) # Same here—translations are applied post-fetch render json: {status: 'success', data: @center}, status: :ok end
4. Bonus: Dynamic Toggling for Queries
If you need to enable/disable translations for specific queries (instead of globally), add scopes to the concern:
# Add this inside the TranslationIntegration concern scope :with_custom_translations, -> { tap { self.custom_translations_enabled = true } } scope :without_custom_translations, -> { tap { self.custom_translations_enabled = false } }
Then use them in controllers:
# Only apply translations for this specific query @centers = Center.with_custom_translations.where(active: true)
Key Notes About Mobility Integration
Your YourGem::Translator.apply_translations function can leverage Mobility's API to handle translations. For example, if you're translating attributes like name and description, your function might look like:
# lib/your_gem/translator.rb module YourGem class Translator def self.apply_translations(record) # Assuming you pass a locale parameter (e.g., from request headers) target_locale = Thread.current[:requested_locale] || I18n.default_locale # Use Mobility's translated attribute methods record.name = record.name_translations[target_locale.to_s] record.description = record.description_translations[target_locale.to_s] # Or use Mobility's built-in locale methods: record.name_in(target_locale) end end end
This setup ensures your gem plays nicely with Mobility while giving you full control over when translations are applied.
内容的提问来源于stack exchange,提问作者Milind Patel

