我有一个名为hardships
的模型,它为投票赞成这种困难的用户提供了一个数组值(:approvals => []
中的hardship_params
)。
我正试图在索引页上创建一个hardships
的列表,列出任何给定的current_user
(使用devise)尚未批准的困难。
数组由用户id组成,因此如果第二个和第三个用户已经批准,@hardship.approvals
的典型值将为["2", "3"]
。
从控制器调用这个的逻辑有问题。我看了很多类似this的帖子,但是无法找到一个适合Rails 5.2和Postgres的答案。
我在找这样的东西:
@need_approval = Hardship.where.not(approvals.include?(current_user.id.to_s))
但是,我知道这不起作用,因为
approvals
不是一个变量,语法也完全错误。有谁能帮我Rails提供信息,让它得到我需要的信息吗?附加信息
这是我的
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
最佳答案
如果我是你,我想我会想创建一个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
相同。