阵列不包含的Rails 5.2控制器

时间:2019-07-18 18:46:36

标签: ruby-on-rails postgresql

我有一个名为hardships的模型,该模型具有一个数组值,用于投票赞成该困难的用户(:approvals => []中的hardship_params)。

我正尝试在索引页面上创建hardships列表,以解决任何给定的current_user(使用设计)均未批准的困难。

该数组由用户ID组成,因此@hardship.approvals的典型值将是["2", "3"],前提是第二个和第三个用户都批准了它。

我无法从控制器调用此逻辑。我看过this之类的SO帖子,但无法收集到适用于Rails 5.2和Postgres的答案。

我正在寻找这样的东西:

@need_approval = Hardship.where.not(approvals.include?(current_user.id.to_s))

但是,我知道那是行不通的,因为approvals不是变量,并且语法都是错误的。谁能帮助我Rails-ify this以便获得我需要的信息?

其他信息

这是我的hardships桌子:

  create_table "hardships", force: :cascade do |t|
    t.string "full_name"
    t.date "date"
    t.string "position"
    t.string "branch"
    t.string "email_non_toca"
    t.string "mobile"
    t.string "address"
    t.string "city"
    t.string "state"
    t.string "zip"
    t.string "bank_name"
    t.string "bank_phone"
    t.string "bank_address"
    t.date "start_date"
    t.boolean "accident", default: false
    t.boolean "catastrophe", default: false
    t.boolean "counseling", default: false
    t.boolean "family_emergency", default: false
    t.boolean "health", default: false
    t.boolean "memorial", default: false
    t.boolean "other_hardship", default: false
    t.string "other_hardship_description"
    t.decimal "requested_amount"
    t.text "hardship_description"
    t.decimal "self_fund"
    t.string "intent_signature"
    t.date "intent_signature_date"
    t.string "release_signature"
    t.date "release_signature_date"
    t.string "status", default: "Application Started"
    t.string "final_decision", default: "Not Decided"
    t.bigint "user_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.boolean "returned", default: false
    t.text "approvals", default: [], array: true
    t.text "rejections", default: [], array: true
    t.index ["user_id"], name: "index_hardships_on_user_id"
  end

1 个答案:

答案 0 :(得分:2)

如果我是你,我想我很想创建一个ApplicationAction模型。像这样:

# == Schema Information
#
# Table name: application_actions
#
#  id               :bigint           not null, primary key
#  user_id          :integer
#  application_type :string
#  application_id   :integer
#  action           :integer
#  created_at       :datetime         not null
#  updated_at       :datetime         not null
#

class ApplicationAction < ApplicationRecord
  belongs_to :user 
  belongs_to :application, polymorphic: true

  enum action: {
    approved:             0,
    rejected:             1,
    requested_to_modify:  2
  }  
end

然后,在您的User模型中,执行以下操作:

# == Schema Information
#
# Table name: users
#
#  id         :bigint           not null, primary key
#  created_at :datetime         not null
#  updated_at :datetime         not null
#

class User < ApplicationRecord
  has_many :application_actions

  %i(
    approved
    rejected
    requested_to_modify
  ).each do |action_sym|
    %w(
      hardship
      scholarship
      charity
    ).each do |application_type|

      # Create the associations: 
      #   - hardship_applications
      #   - scholarship_applications
      #   - charity_applications
      has_many "#{application_type}_applications".to_sym,
        -> { distinct },
        through:      :application_actions,
        source:       :application,
        source_type:  application_type.camelize

      # Define the methods:
      #   - approved_application_actions
      #   - rejected_application_actions
      #   - requested_to_modify_application_actions
      define_method("#{action_sym}_application_actions") do 
        application_actions.send(action_sym)
      end

      # Define the methods:
      #   - approved_hardship_applications
      #   - rejected_hardship_applications
      #   - requested_to_modify_hardship_applications
      #   - approved_scholarship_applications
      #   - rejected_scholarship_applications
      #   - requested_to_modify_scholarship_applications
      #   - approved_charity_applications
      #   - rejected_charity_applications
      #   - requested_to_modify_charity_applications
      define_method("#{action_sym}_#{application_type}_applications") do 
        send("#{application_type}_applications").
          joins(:application_actions).
          where(
            application_actions: {
              action: ApplicationAction.actions[action_sym]
            }
          )
      end

      # Define the methods:
      #   - hardship_applications_not_approved
      #   - hardship_applications_not_rejected
      #   - hardship_applications_not_requested_to_modify
      #   - scholarship_applications_not_approved
      #   - scholarship_applications_not_rejected
      #   - scholarship_applications_not_requested_to_modify
      #   - charity_applications_not_approved
      #   - charity_applications_not_rejected
      #   - charity_applications_not_requested_to_modify
      define_method("#{application_type}_applications_not_#{action_sym}") do 
        application_type.
          camelize.
          constantize.
          where.
          not(id: send("#{action_sym}_#{application_type}_applications"))
      end

    end
  end

end

然后,在您的Hardship模型中,执行以下操作:

# == Schema Information
#
# Table name: hardships
#
#  id               :bigint           not null, primary key
#  application_type :integer          default(NULL)
#  created_at       :datetime         not null
#  updated_at       :datetime         not null
#

class Hardship < ApplicationRecord
  has_many :application_actions, as: :application

  enum application_type: {
    accident:           0,
    catastrophe:        1,
    counseling:         2,
    family_emergency:   3,
    health:             4,
    memorial:           5,
    other_hardship:     6
  }
end

然后,如果我通过快速RSpec测试运行它:

require 'rails_helper'

RSpec.describe 'Hardship Applications' do
  before(:each) do 
    @user_1               = User.create!
    @user_2               = User.create!
    @hardship_1           = Hardship.create!
    @user_1.
      application_actions.
      create!(application: @hardship_1).
      approved!
    @user_2.
      application_actions.
      create!(application: @hardship_1).
      rejected!
  end
  it "user_1 approved_hardship_applications to include hardship_1" do 
    expect(@user_1.approved_hardship_applications).to include(@hardship_1)
  end
  it "user_1 hardship_applications_not_approved NOT to include hardship_1" do 
    expect(@user_1.hardship_applications_not_approved).not_to include(@hardship_1)
  end
  it "user_1 rejected_hardship_applications NOT to include hardship_1" do 
    expect(@user_1.rejected_hardship_applications).not_to include(@hardship_1)
  end
  it "user_2 approved_hardship_applications NOT to include hardship_1" do 
    expect(@user_2.approved_hardship_applications).not_to include(@hardship_1)
  end
  it "user_2 hardship_applications_not_approved to include hardship_1" do
    expect(@user_2.hardship_applications_not_approved).to include(@hardship_1)
  end
  it "user_2 rejected_hardship_applications to include hardship_1" do 
    expect(@user_2.rejected_hardship_applications).to include(@hardship_1)
  end
end

我知道...

Hardship Applications
  user_1 approved_hardship_applications to include hardship_1
  user_1 hardship_applications_not_approved NOT to include hardship_1
  user_1 rejected_hardship_applications NOT to include hardship_1
  user_2 approved_hardship_applications NOT to include hardship_1
  user_2 hardship_applications_not_approved to include hardship_1
  user_2 rejected_hardship_applications to include hardship_1

Finished in 0.13431 seconds (files took 0.90021 seconds to load)
6 examples, 0 failures

因此,您可以这样做:

@need_approval = current_user.hardship_applications_not_approved

代替:

@need_approval = Hardship.where.not(approvals.include?(current_user.id.to_s))

您还会注意到,在Hardship模型中,我将所有应用程序类型都设置为enum。这将减少空白字段(假设Hardship应用程序只能是一种应用程序类型)。

似乎还有其他减少冗余的机会。例如,您可以创建PhysicalAddressPhoneNumberEmailAddress模型,并将它们与每种类型的应用程序相关联。您还可以将应用程序status创建到enum,并将其默认设置为application_started。与final_decision相同。