【问题标题】:Rails modeling for a userRails 为用户建模
【发布时间】:2010-05-23 01:13:13
【问题描述】:

在构建允许用户登录和创建数据的 Rails 应用程序时,是否最好在每个模型上设置 belongs_to :user 关联?例如,假设用户可以创建收藏夹、颜色和标签。

假设收藏夹has_many :tags 和颜色也has_many :tags。假设用户是唯一有权编辑这些标签的人,对belong_to :user 的标签仍然很重要吗?

还有一个类似的问题:在更新 FavoritesController 中的数据时,我得出的结论是,您总是通过执行类似 current_user.favorites.find(param[:id].update_attributes(param[:favorite]) 的操作来执行 CRUD 操作,这样它们肯定只能更新属于给他们。对吧?

更新 对任何答案都不太满意,因为没有人真正回答我的问题,而是采用了仅作为示例的标签模型,提出了更好的方法。我假设我是对的,模型应该属于 :user。我还在这里发现了一些很好的安全提示来解决我的问题:http://asciicasts.com/episodes/178-seven-security-tips

【问题讨论】:

    标签: ruby-on-rails data-modeling conventions


    【解决方案1】:

    当您描述标签时,它们似乎更像是一个方面,因此您可以将它们实现为多态关联。但是你应该做多对多,因为标签可以在用户和可标记对象之间重复使用。我们将连接模型称为Tagging,如果您想记住是谁创建了标记,它将是属于用户的模型。

    class Tag < ActiveRecord::Base
      has_many :taggings, :dependent => :destroy
      has_many :colors, :through => :taggings, :source => :taggable, :source_type => "Color"
      has_many :favorites, :through => :taggings, :source => :taggable, :source_type => "Favorite"
    end
    
    class Tagging < ActiveRecord::Base
      belongs_to :user
      belongs_to :taggable, :polymorphic => true
      belongs_to :tag  
    end
    
    class Color < ActiveRecord::Base
      belongs_to :user
      has_many :taggings, :as => :taggable
      has_many :tags, :through => :taggings
    end
    
    class Favorite < ActiveRecord::Base
      belongs_to :user
      has_many :taggings, :as => :taggable
      has_many :tags, :through => :taggings
    end
    
    class User < ActiveRecord::Base
      has_many :favorites
      has_many :colors
      has_many :taggings
      has_many :tags, :through => :taggings
    end
    

    至于收藏更新,我同意你的看法:你将主要在用户范围内工作(很可能是当前登录的用户)。

    【讨论】:

      【解决方案2】:

      这取决于您的型号。这两种情况都是有效的,但我不赞成建立这样的循环关系。具有层次结构更加灵活。例如:User->Favorites->Tags(除非你也想标记用户)

      User.favorites.find(params[:id]).update_attributes(param[:favorite])
      

      就是我猜的意思(语法)。调用 URL 的人将执行该操作。不要依赖该 URL 仅对一个用户可见(收藏夹的所有者)这一事实。您应该检查当前登录的用户是唯一对属于他的对象执行操作的用户。

      【讨论】:

      • 我的原始代码有一个错误:我通常使用current_user.favorites 而不是User.favorites。这就是你所说的检查到位的意思吗?这就是我目前所做的所有工作,以确保用户正在编辑他们的数据而不是其他用户的数据。
      【解决方案3】:

      对我来说,提议的机制听起来有点太复杂了。我更喜欢current_user 方式。假设您的身份验证系统中有一个current_user(遵循authlogic 方式),然后在每个相关表中简单地添加一个用户references(user_id)。通过控制器 filter 更新 current_user 以获取新记录或更新记录。

      在模型中,相应地放入相关的belongs_to :users,如果需要,在用户模型中放入足够的has_many

      【讨论】:

        【解决方案4】:

        :has_many 和 :belongs_to 在 AR 中将解释模型之间的关系,但不一定必须在模型中使用它们,它们之间的关联已经作为外键存在于表中。

        但是在你的模型中添加 :has_many 或 :belongs_to 会给你的模型提供额外的方法

        例如:

        
        class User < ActiveRecord::Base
         has_many :favorites
        
        

        #def favorites # Favorite.find_all_by_user_id(self.id) # end end

        如果您提及 has_many,它将在您的模型中提供一个名为收藏夹的新方法,该方法将是不可见的(将出现在 AR 中)。

        对于任何关联类似,如果您打算使用这种方法,您应该在模型中使用关联。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2016-12-30
          • 2013-01-23
          • 1970-01-01
          • 2015-08-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多