如何设计警察罚款数据库?

Posted

技术标签:

【中文标题】如何设计警察罚款数据库?【英文标题】:How to design a database for police fines? 【发布时间】:2021-03-29 21:36:14 【问题描述】:

使用 Rails 6 我正在设计一个管理警察罚款的应用程序。一个用户可以违反多篇文章,一篇文章可以有多个字母,一个字母可以有多个逗号。

这是我的实现:

#models/fine.rb
class Fine < ApplicationRecord
  has_many :violations
  has_many :articles, through: :violations
  has_many :letters, through: :violations
  has_many :commas, through: :violations
end
#models/article.rb
class Article < ApplicationRecord
  has_many :letters
  has_many :violations
  has_many :fines, through: :violations
end
#models/letter.rb
class Letter < ApplicationRecord
  belongs_to :article
  has_many :commas

  has_many :violations
  has_many :fines, through: :violations

end
#models/comma.rb
class Comma < ApplicationRecord
  belongs_to :letter

  has_many :violations
  has_many :fines, through: :violations
end
#models/violation.rb
class Violation < ApplicationRecord
  belongs_to :fine

  belongs_to :article
  belongs_to :letter, optional: true
  belongs_to :comma, optional: true
end

当我以 PDF 格式打印罚款时,我需要显示违规行为:文章、字母和逗号。我很难创建一个表格来编译罚款,因为它太深了。我正在使用 Active Admin,当我创建新的罚款时,我想关联许多违规行为。

违规示例:

Violation.new
 => #<Violation id: nil, article_id: nil, fine_id: nil, letter_id: nil, comma_id: nil, note: nil, created_at: nil, updated_at: nil> 

如何创建一个表单(使用 Active Admin,它使用 Formtastic)将许多违规行为与罚款相关联?示例表格:

示例(带有示例数据):

Violation.new fine: fine, article: a, letter: a.letters.last, comma: a.letters.second.commas.last
 => #<Violation id: nil, article_id: 124, fine_id: 66, letter_id: 10, comma_id: 4, note: nil, created_at: nil, updated_at: nil> 

【问题讨论】:

你能把它缩小到这个设置给你调试的特定问题吗?如果不真正了解整个应用程序和所有细节,很难告诉你这是否正确。 【参考方案1】:

在我看来,您的问题相当模糊,仅根据提供的信息很难回答。由于我无法给出肯定会解决您问题的答案,请允许我尝试为您指明正确的方向。

呈现表单

首先让我们了解这里的问题:您正在尝试在嵌套资源表单中创建关联记录

您需要为Fine 自定义表单以包含每个违规的表单。看how ActiveAdmin handles nested resources。它应该是这样的:

ActiveAdmin.register Fine do
  form do |f|
    inputs 'Violations' do
      f.has_many :violations do |vf|
        vf.input :article, as: :select, collection: Article.all
        vf.input :letter, as: :select, collection: Letter.all
        vf.input :comma, as: :select, collection: Comma.all
      end
    end
  end
end

简而言之,这就是您问题的答案“我如何创建一个表单(使用 Active Admin,他们使用 Formtastic)将许多违规行为与罚款相关联?”

注意事项

您可能已经注意到,这种方法存在一些问题。

首先,它与您的示例完全不同。您可以使用 as: :check_boxes 轻松更改 Formtastic 以添加复选框,但您会发现复选框并没有按照您想要的方式组织,并带有漂亮的缩进。据我所知,您无法使用 Formtastic 做到这一点。相反,我相信你必须使用a partial。

使用部分文章,您可以轻松浏览文章,并为每个文章呈现一个复选框并浏览每个人的信件,等等。但是,请记住,此表单将要求您 customize the controller,以便它了解每个复选框并创建相应的违规行为。不是那么直截了当。

其次,这里没有强制执行数据完整性。可以选择一篇文章、另一篇文章的字母和第三篇文章的逗号(顺便说一句,我希望你有一个验证来保护你免受这种情况的影响)。要使表单动态更改,因此在选择后仅显示给定文章的字母,逗号也是如此,需要一些客户端逻辑。如果你问我,不值得麻烦。

结论

无论是回答还是解决,您的问题都远非简单明了。您始终拥有的一个选项是一组自定义路由,用于在 ActiveAdmin 之外管理此类资源。请记住,像这样的工具仅与它们从您那里获得的工作一样有价值。如果你不得不与之抗争,最好只是互相让开。

希望这对您有所帮助。

【讨论】:

【参考方案2】:

已解决:

  f.has_many :violations do |vf|
    vf.input :article, as: :select, include_blank: false, collection: options_for_select(Article.all.map |article| [article.number, article.id,  :'data-article-id' => article.id, :'data-letters' => article.letters.map(&:id).to_json ])
    vf.input :letter, as: :select, collection: options_for_select(Letter.all.map |letter| [letter.letter, letter.id,  :'hidden' => true, :'data-letter-id' => letter.id, :'data-article-id' => letter.article.id, :'data-commas' => letter.commas.map(&:id).to_json ])
    vf.input :comma, as: :select, collection: options_for_select(Comma.all.map |comma| [comma.number, comma.id,  :'hidden' => true, :'data-comma-id' => comma.id, :'data-letter-id' => comma.letter.id ])
  end

还有一点 javascript:

$(document).on('has_many_add:after', '.has_many_container', function (e, fieldset, container) 
    selects = fieldset.find('select');
    article_select = selects[0];
    letter_select = selects[1];
    comma_select = selects[2];

    $(article_select).on("change", function () 
        $(letter_select).prop('selectedIndex', 0);
        $(comma_select).prop('selectedIndex', 0);
        $("#" + letter_select.id + " option").prop("hidden", true);
        $("#" + comma_select.id + " option").prop("hidden", true);

        letters = $(this).find(':selected').data('letters');

        $.each(letters, function (index, id) 
            $("#" + letter_select.id + " option[data-letter-id='" + id + "']").removeAttr("hidden");
        );
    );

    $(letter_select).on("change", function () 
        $(comma_select).prop('selectedIndex', 0);
        $("#" + comma_select.id + " option").prop("hidden", true);

        commas = $(this).find(':selected').data('commas');

        $.each(commas, function (index, id) 
            $("#" + comma_select.id + " option[data-comma-id='" + id + "']").removeAttr("hidden");

        );
    );
);

我在选择框中显示所有文章、字母和逗号。最初逗号和字母是隐藏的,然后当用户单击文章时,字母的选择框仅显示相关的字母。 逗号代码与字母相同。 在我可以在 Violation 模型中添加一些验证之后。

【讨论】:

以上是关于如何设计警察罚款数据库?的主要内容,如果未能解决你的问题,请参考以下文章

名悦集团提醒新手上路要注意的“电子警察”,开车不受罚

微信可查违章交罚款!黑龙江交管业务“单点登录全网通办”

WhatsApp 因泄露用户信息,与 Facebook 共享数据被爱尔兰罚款 2.25 亿欧元

警察扫描无线电应用程序如何工作?具体来说,他们从哪里获取流式音频数据?

降低欧洲隐私罚款风险的4种方法

Java设计模式------------策略模式