【问题标题】:Managing child relationships with a nested attribute form使用嵌套实体形式管理子关系
【发布时间】:2009-08-06 17:24:23
【问题描述】:

我想要做的是:

任何时候用户都可以拥有 1 个有效的个人资料。此活动配置文件必须由管理员授权,以确保其符合站点的规则和规定。当用户编辑他们的个人资料时,他们的公开个人资料不受影响,直到管理员签署他们的更改。如果他们在个人资料审核期间进行了编辑,他们的修改将应用于待审核的未完成个人资料并被推到队列的最后。

我的模型看起来像这样:

class Profile < AR:B
    belongs_to :user
end

class User < AR:B
    has_many :profiles do
        def active
            ...
        end
        def latest
        end
    end
    def profile
        self.profiles.active
    end
end

有一个小转折......用户不应该直接编辑配置文件,因为配置文件集合没有公开。相反,他们编辑了他们的用户,并且个人资料字段显示在那里。

管理此问题的最佳方法是什么?目前我正在使用:

accepts_nested_attributes_for :profiles

在用户中,但这似乎很 hacky。理想情况下,大部分逻辑都存在于模型中,但我正在考虑的另一件事是使用演示者。

任何想法将不胜感激,如果您需要更多信息作为评论,请告诉我,我会适当地更新这篇文章。

【问题讨论】:

    标签: ruby-on-rails nested-attributes has-one activeview


    【解决方案1】:

    也许您应该尝试建立从用户到配置文件的两种关系。一个是他们可以通过您的用户界面编辑的,另一个是管理员批准的。

    它可以像这样工作:

    class User < AB:B
    
    has_one :profile #the user-editable one one
    has_one :active_profile, :class_name=>"profile" #the one shown
    
    end
    

    然后通过表单对用户配置文件进行的每个更改都会显示给管理员(使用和观察者,或者可能只是和“after_save”过滤器)。当它批准后,更改将转储到 active_profile 之一,并显示在某处。

    这样,您可以拥有一个干净的表单界面,并且每当他们再次编辑它时,他们都会看到最新的(但未批准的)个人资料。您还可以使用 updated_at 列对队列进行排序,以获得“他们的编辑将应用于未完成的配置文件以供审核,并被推到队列的后面”功能。

    【讨论】:

    • 最初我想这样做,但因为我认为它不理想而放弃了它,但是你的文章让我相信这是正确的方法,并且很可能会让我视图和模型中的逻辑更简单。
    • 我可能应该提到,在这种情况下,FK 需要在用户模型上以区分两个配置文件,因此它将是 belongs_to 而不是 has_one。
    • 是的,你说得对。虽然在语义上有点奇怪,但与 BD 相关的那将是正确的。
    【解决方案2】:

    我会通过让用户模型与上面建议的两个配置文件建立关系来解决这个问题。一个“已批准”配置文件,一个用于编辑的配置文件进入您的管理队列。

    但是,为了处理“待定”配置文件和“已批准”配置文件之间的转换,我建议可能添加一个状态机来处理转换。 AASM gem 在最近的一个项目中对我有好处。 (http://github.com/rubyist/aasm/tree/master),我相信 Edge Rails 也刚刚推出了 State Machinage。 (http://github.com/rails/rails/commit/aad5a30bf25d8a3167afd685fc91c99f4f09cc57)

    您的模型可能如下所示:

    class User < AR:B
    
    has_one :active_profile 
    has_one :pending_profile
    
    include ActiveRecord:: StateMachine
    
    state_machine do
       state :approved
       state :pending
       state :rejected
    
       event :update_profile_pending do
        transitions :to => :pending, :from => [:approved], :on_transition => :send_to_admin_queue
      end
    
       event :update_profile_approved do
        transitions :to => :approved, :from => [:pending], :on_transition => :update_current_profile
       end
    
       event :update_to_rejected do
        transitions :to => :rejected, :from => [:pending]
      end
    end
    
    def send_to_admin_queue
      //method to handlesending pending profiles to admin for approval
    end
    
    def update_current_profile
     //method to handle updated profiles with changes
    end
    
    end
    

    然后您可以调用 User.update 配置文件挂起!或 User.update 个人资料已获批准!在您的个人资料状态之间转换,并使用转换回调来处理在您的活动个人资料和待定个人资料之间发送编辑数据。

    至于在您的实际表单中使用nested_attributes_for,我不认为这是一个hack,我也使用它来更新嵌套属性并且它可以正常工作。在这种情况下,虽然您可能不需要太多,因为您有 2 个配置文件(一个公开,一个待定)。

    只是一个想法!在这里大声思考!

    【讨论】:

    • 感谢您的回答。我看到状态机被塞进了边缘......我真的很期待rails 3.0!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-01-05
    • 2013-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-25
    相关资源
    最近更新 更多