代码之家  ›  专栏  ›  技术社区  ›  zetetic

按顺序执行Rails虚拟属性设置器

  •  0
  • zetetic  · 技术社区  · 16 年前

    作为解决方法,我分两步构建对象

    @other_model = @some_model.build_other_model
    @other_model.setup(params[:other_model)
    

    setup

    class OtherModel < ActiveRecord::Base
      def setup(other_params)
         # execute the important_attribute= setter first
        important_attribute = other_params.delete(:important_attribute)
    
         # set the other attributes in whatever order they occur in the params hash
        other_params.each { |k,v| self.send("#{k}=",v) }
      end
    end
    

    这似乎管用,但看起来很笨拙。有更好的办法吗?

    编辑

    每 neutrino SomeModel :

    class SomeModel < ActiveRecord::Base
      def build_other_model(other_params)
        other_model = OtherModel.new(:some_model=>self)
        other_model.setup(other_params)
        other_model
      end
    end
    
    2 回复  |  直到 9 年前
        1
  •  1
  •   alex.zherdev    16 年前

    这是一件好事,你有这样的操作在一个特定的时间 OtherModel 的方法,因为您可以只调用此方法,而不必担心赋值的顺序。所以我会离开这部分,但只是从一个 SomeModel 的方法:

    class SomeModel < ActiveRecord::Base
      def build_other_model(other_params)
        other_model = build_other_model
        other_model.setup(other_params)
        other_model
      end
    end
    

    @other_model = @some_model.build_other_model(params[:other_model])
    
        2
  •  0
  •   mikeweber    15 年前

    我接受了您在setup方法中首先删除重要属性的想法,但使用了alias\u chain\u方法,使其更透明:

    def attributes_with_set_important_attribute_first=(attributes = {})
      # Make sure not to accidentally blank out the important_attribute when none is passed in
      if attributes.symbolize_keys!.include?(:important_attribute)
        self.important_attribute = attributes.delete(:important_attribute)
      end
    
      self.attributes_without_set_important_attribute_first = attributes
    end
    
    alias_method_chain :attributes=, :set_important_attribute_first
    

    这样,您的代码就不会改变正常的Rails样式

    @other_model = @some_model.other_models.build(params[:other_model])