我有一个名为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
答案 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
应用程序只能是一种应用程序类型)。
似乎还有其他减少冗余的机会。例如,您可以创建PhysicalAddress
,PhoneNumber
和EmailAddress
模型,并将它们与每种类型的应用程序相关联。您还可以将应用程序status
创建到enum
,并将其默认设置为application_started
。与final_decision
相同。