Ruby on rails Postgres用户模式&;批准约会风格应用程序的用户

Ruby on rails Postgres用户模式&;批准约会风格应用程序的用户,ruby-on-rails,postgresql,activerecord,Ruby On Rails,Postgresql,Activerecord,用户查看其他用户的个人资料并标记批准或拒绝、ala Tinder或类似的约会应用程序 我正在构建一个后端带有ActiveRecord和PostgreSQL的Rails服务器 我正在考虑一个用户模型,然后是一个批准模型,该模型具有用户id和批准id create_table "approvals", force: :cascade do |t| t.integer "user_id" t.integer "approved_id" t.integer "relat

用户查看其他用户的个人资料并标记
批准
拒绝
、ala Tinder或类似的约会应用程序

我正在构建一个后端带有ActiveRecord和PostgreSQL的Rails服务器

我正在考虑一个
用户
模型,然后是一个
批准
模型,该模型具有
用户id
批准id

  create_table "approvals", force: :cascade do |t|
    t.integer  "user_id"
    t.integer  "approved_id"
    t.integer  "related_approval_id"
批准:

  create_table "approvals", force: :cascade do |t|
    t.integer  "user_id"
    t.integer  "approved_id"
    t.datetime "created_at",         null: false
    t.datetime "updated_at",         null: false
    t.datetime "user1_approval"
    t.datetime "user2_approval"
    t.datetime "denied_at"
  end


class User

  has_many :approvals
  has_many :approved, through: :approvals
  has_many :inverse_users, class_name: "Approval", foreign_key: "approved_id"
  has_many :inverse_approvals, through: :inverse_users, source: :user

class Approval

    def self.user_approval(user1, user2)
        sorted = [user1, user2].sort_by { |u| u.name}
        Approval.find_or_create_by(user: sorted[0], approved: sorted[1])
    end
这样做的优点是限制了
批准
对象的数量-每对
用户
对象只有1个。但是,我不确定如何使用此模式有效地进行查询

例如,在查找
approve
reject
操作时,我必须手动检查提交的
user\u id
是否与
user\u id
approved\u id
匹配,以适当设置
user1\u approval
user2\u approval

我正在考虑通过一个简单的过滤器查找
用户
s(年龄范围在10岁以内)

因此,在
User
中,我有:

def self.eligible(user) 
    users = User.where('age >= ? AND age <= ? AND id != ?', user.lowest_eligible_age,user.maximum_eligible_age, user.id).limit(20)

    approvals = []
    users.each do |u|
      approvals.push(Approval.user_approval(user, u ))
    end

    approvals.reject! { |a| a.denied_at}

    approvals

  end
这样做会在数据库中产生更多的行


我希望这是有道理的。我正在寻找一个好的架构解决方案,用于用户之间的相互批准和拒绝,它允许我进行良好的查询,例如仅显示当前用户未批准且未拒绝当前用户的
用户,将这种模式称为决策更有意义。我是这样看待这一切的

用户模型 用户模型表示将对另一个用户或另一个用户做出决定的应用程序的任何用户

决策模型 决策表示用户之间的任何交互。对用户进行右击是一个决定。另一个决定是从对方用户处直接做出响应。这不是表示为一个整体对象,而是表示为两个独立的“决策”交互

让我解释一下决策中的字段是什么意思:

  • 决策者id-进行刷卡的用户的id
  • decision_receiver_id-接收swip的用户的id
  • approved-一个布尔值,如果向右滑动则为true,如果向左滑动则为false
  • active—一个布尔值,用于确定此决策是否有回复决策
决策模型中需要一个保存前回调,该回调将检查正在保存的决策是否已经有对应的回复决策。如果是这样的话,你会想让这个决定不再有效,这样它就不会再出现在提要上了。然后,您可以在应用程序中通知用户他们同意/不同意或您希望做的任何事情

before_save: check_for_existing_reply

def check_for_existing_reply
  # if there is a decision object with this decision_maker_id and this 
  # decision_receiver_id but in opposite fields then you know there is a reply 
  # and you can take some action here
end  
用户模型中,您可以编写查找所有存在的活动批准/拒绝的方法

scope :decisions, -> (id, approval_type) { where('decision_receiver_id = ? AND approved = ? AND active = true', approval_type) }  
通过使用
User.decisions(User\u id,true)
调用该范围,您可以获得用户的所有批准。通过使用
user.decisions(user\u id,false)
调用该作用域,您可以获得用户的所有拒绝

您还可以将其分为两个单独的范围,一个用于批准,另一个用于拒绝

scope :approvals, -> (id) { where('decision_receiver_id = ? AND approved = ? AND active = true', true) } 
scope :rejections, -> (id) { where('decision_receiver_id = ? AND approved = ? AND active = true', false) }  
最后,可以将此方法设置为对用户实例调用的方法,这样就不必传入id参数

# where decision = true would mean approvals and decision = false would mean rejections  
def get_decisions(decision)  
   return User.where('decision_receiver_id = self.id AND approved = decision AND active = true') }  
end

您可以在用户实例上调用它,比如
User.get\u decisions(true)

@Mike给了我很好的建议,但我真的不明白为什么
批准
/
拒绝
范围应该在
用户
模型中,因为在范围级别上,模型不知道与该
用户关联的
决策
,而且,用户模型没有
decision\u receiver\u id
,因此在尝试调用此作用域时,很可能会出现ORM错误,例如
error:column“seller\u id”在字符38处不存在。
scope :approvals, -> (id) { where('decision_receiver_id = ? AND approved = ? AND active = true', true) } 
scope :rejections, -> (id) { where('decision_receiver_id = ? AND approved = ? AND active = true', false) }  
# where decision = true would mean approvals and decision = false would mean rejections  
def get_decisions(decision)  
   return User.where('decision_receiver_id = self.id AND approved = decision AND active = true') }  
end