Rails simple_form 如何根据不同的 url 使用不同的设置

heroyct · 2022年06月22日 · 最后由 heroyct 回复于 2022年06月29日 · 255 次阅读

simple_form可以在 config/initializers 里面进行设置,对于所有画面都使用统一的界面没什么问题。

现在想根据不同的 URL 来使用不同的设置,看了下文档,button_class label_text default_wrapper 等属性好像只可以设置一个。

想知道能不能这样设置,因为面向用户和面向 admin 使用的是完全不同的界面。

  • URL /user/* 使用 user 专用的设置。
  • URL /admin/* 使用 admin 专用的设置。
  • URL /operator/* 使用 operator 专用的设置。

不知道有没有人遇到类似的问题。

看了下 ISSUE 好像不打算实现类似的 feature,在项目里面扩展了一下。

class Admin::BaseController < ApplicationController
  around_action :use_simpleform_admin
  def use_simpleform_admin
    SimpleForm.use_namespace(:admin) do
      yield
    end
  end

Config

SimpleForm.use_namespace(:admin) do
  SimpleForm.setup do |config|
    # some config for admin only
  end
end

extend

# frozen_string_literal: true
require 'simple_form'
require 'simple_form/form_builder'
module SimpleForm
  module Namespace
    extend ActiveSupport::Concern

    DEFAULT_VALUES = SimpleForm.class_variables.index_with {|k| SimpleForm.class_variable_get(k) }

    def current_wrappers
      current_configuration[:@@wrappers]
    end

    def use_namespace(name = :default)
      old_namespace = current_namespace
      switch_namespace(name)
      yield
    ensure
      switch_namespace(old_namespace)
    end

    def switch_namespace(namespace)
      Thread.current[:simple_form_namespace] = namespace
    end

    def current_namespace
      Thread.current[:simple_form_namespace] ||= :default
    end

    def builder_discovery_cache
      current_configuration[:@@discovery_cache] ||= {}
    end

    def custom_wrapper_mappings
      current_configuration[:@@custom_wrapper_mappings] ||= {}
    end
  end

  extend Namespace
  @configurations = {}
  def self.current_configuration
    @configurations[current_namespace] ||= Namespace::DEFAULT_VALUES.deep_dup
  end

  SimpleForm.class_variables.each do |k|
    method = k.to_s.tr("@@", '')
    setter_method = "#{method}="
    if SimpleForm.respond_to?(setter_method)
      define_singleton_method(setter_method) do |v|
        current_configuration[k] = v
      end
    end
    next unless SimpleForm.respond_to?(method)
    define_singleton_method(method) do
      current_configuration[k]
    end
  end

  def self.wrapper(name)
    current_wrappers[name.to_s] or raise WrapperNotFound, "Couldn't find wrapper with name #{name}"
  end

  # Define a new wrapper using SimpleForm::Wrappers::Builder
  # and store it in the given name.
  def self.wrappers(*args, &block)
    if block_given?
      options                 = args.extract_options!
      name                    = args.first || :default
      current_wrappers[name.to_s] = build(options, &block)
    else
      current_wrappers
    end
  end

  SimpleForm::FormBuilder.define_singleton_method(:discovery_cache) do
    ::SimpleForm.builder_discovery_cache
  end
end
需要 登录 后方可回复, 如果你还没有账号请 注册新账号