我正在使用ActiveModel::Dirty来跟踪表单中所做的更改。现在一切都按我的预期进行。对于像电话号码这样在表单中出现破折号的东西,我只需对其进行格式化,然后电话号码就不会出现在.changed
预期行为的列表中。
但是,我遇到了一个问题,即我在配置文件模型中使用 jsonb 字段。所以问题是 ActiveModel 会将 JSONB 字段列为已更改,即使我专门对其进行格式化以匹配它之前的外观。这不是预期的行为。更奇怪的是,我的另一个 JSONB 专栏并没有经历这种疯狂。
我遇到问题的 JSONB 字段看起来像这样,
store_accessor :user_details, :names, :other_field
store_accessor :bank_details, :bank_city, :bank_name
user_details
并且bank_details
是 jsonb 列。需要注意的一些事情:names 是一个数组,other_field 是一个字符串。bank_city 和bank_name 是字符串。
任何人都可以深入了解为什么 :user_details 特别是在解决这个问题,而不是 :bank_details JSON 列?
我怀疑这可能是由于我在 :user_details 中使用了一个数组,并且我怀疑 ActiveModel 源代码中的某处发生了比较,但也许我错了?
编辑:我发现这肯定是因为我使用数组来表示:名称。我将其更改为字符串,它不再认为 JSON 列已更改。我要深入研究 ActiveModel 源代码,看看是否能找到原因。
编辑#2:出于某种原因,我以为我什么都不做就解决了这个问题,但我是一个假人,意识到我已经删除了表单中的某些内容。所以这个问题对我来说还没有解决。任何见解都会令人惊奇。通过查看 ActiveModel::Dirty 源代码,我无法弄清楚为什么会发生这种情况。我不完全确定该去哪里寻找。去打一下byebugs看看是否有帮助。
编辑#3:重复此问题的步骤
创建带有 JSONB 列的 Rails 模型。设置商店访问器,您只需要一个即可完成此操作。使用验证器或格式化程序将其默认设置为空数组。为您的模型提供 ActiveModel::Dirty 包含。运行 Rails 控制台。运行以下命令。假设 user_details 是 JSONB 列,其存储访问器是名称。
a = Profile.user_details
a.user_details = { "names" => [{"first_name" => "", "last_name" …
Run Code Online (Sandbox Code Playgroud) 可以使用没有rails的ActiveModel吗?可以在桌面应用程序中使用ActiveModel吗?
我有一个支持ActiveModel缓存的gem有问题.当我使用观察者缓存模型时,在应用程序初始化期间,它会尝试描述表以获取所有字段名称.
rake任务运行时也会执行相同的操作,包括db:migration.在这种情况下,存在一些循环引用错误.我想检测当前的rake任务,跳过gem初始化,但我不知道如何找出通过rake任务调用的代码.怎么检查?
简介:我正在尝试在自定义ActiveModel::EachValidator
验证器中更改属性的值.鉴于以下原型:
def validate_each(record, attribute, value)
试图设置value = thing
似乎没有做任何事情 - 我错过了什么?应该有一个聪明的方法来做到这一点......
细节:我接受URL输入作为网站的一部分.我不想只是采取URL,并直接验证它返回一个200 OK
消息,因为这会忽略没下手的条目http
,或者留出了领先www
,等我有一些自定义的逻辑来处理这些错误,并按照重定向.因此,如果用户键入而不是,我希望验证成功.逻辑在验证中正常工作,但问题是如果有人在前者中键入,则数据库中的存储值是"错误"形式而不是更新好的形式.我可以在验证过程中将条目更改为更规范的表单吗?example.org/article
http://www.example.org/article
使用ActiveAttr
:
class Filter
include ActiveAttr::Model
attribute term
# Overriding to_key, to_param, model_name, param_key etc doesn't help :(
end
class SpecialFilter < Filter
end
Run Code Online (Sandbox Code Playgroud)
如何覆盖ActiveModel以生成所有子类的(相同)预定义输入名称?
= form_for SpecialFilter.new, url: 'xx' do |f|
= f.text_field :term
Run Code Online (Sandbox Code Playgroud)
所以,而不是<input name='special_filter[term]' />
我需要得到<input name='filter[term]' />
注意:场景更复杂(使用simple_form和radio/checkboxes/dropdown等),因此请不要建议更改类的名称或类似的解决方法.我确实需要使用表单生成器使用的一致名称.
我需要在email_list中验证电子邮件保存.为验证我有EmailValidator.但我无法弄清楚如何在validates_each对中使用它.还有其他方法可以进行验证吗?
class A < ActiveRecord::Base
serialize :email_list
validates_each :email_list do |r, a, v|
# what should it be here?
# EmailValidator.new(options).validate_each r, a, v
end
end
Run Code Online (Sandbox Code Playgroud) validation serialization activerecord ruby-on-rails activemodel
我正在开发一个小型Rails项目,它只允许用户提交表单,表单中的信息通过API调用发送到另一个服务进行消费.
这是我的模型:
class ServiceRequest
include ActiveModel::Model
include ActiveModel::Validations
extend ActiveModel::Naming
attr_accessor :first_name, :last_name, :prefix, :contact_email, :phone_number,
:address, :address2, :city, :state, :zip_code, :country,
:address_type, :troubleshooting_reference, :line_items
validates_presence_of :first_name, :last_name, :contact_email, :phone_number,
:address, :city, :state, :zip_code, :country, :address_type,
:troubleshooting_reference
def initialize(attributes = {})
super
@errors = ActiveModel::Errors.new(self)
@api_response = nil
end
def line_items_attributes=(attributes)
@line_items ||= []
attributes.each do |i, params|
@line_items.push(LineItem.new(params))
end
end
def save
conn = Faraday.new(url: "#{Figaro.env.arciplex_url}") do |faraday|
faraday.request :url_encoded
faraday.response :logger
faraday.adapter Faraday.default_adapter
end
@api_response = conn.post do …
Run Code Online (Sandbox Code Playgroud) 仅当当前更新修改了我的列状态值时,我才尝试在我的 rails 应用程序中发送通知电子邮件。我尝试按照某些帖子和status_changed?
方法中的建议使用 Active Model Dirty 。不幸的是,我的电子邮件从未发送过,因为@partnership.status_changed?即使状态的值在上次更新期间确实发生了变化,也会不断返回 false。这是我的控制器代码:
def update
authorize @partnership
if @partnership.update(partnership_params)
send_notification_email
render json: {success: "partnership successfully updated"}, status: 200
else
render_error(nil, @partnership)
end
end
private
def send_notification_email
PartnershipMailer.partnership_status_change(@partnership).deliver_now if @partnership.status_changed?
end
Run Code Online (Sandbox Code Playgroud)
我还在我的模型中包含了 Active Model Dirty :
class Partnership < ActiveRecord::Base
include ActiveModel::Dirty
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么 ?
我有一个像这样的无表模型:
class SomeModel
include ActiveModel::Model
attribute :foo, :integer, default: 100
end
Run Code Online (Sandbox Code Playgroud)
我正在尝试使用下面链接中的一个属性,它在普通模型中完美运行,但是我无法让它在无表模型中运行。
https://api.rubyonrails.org/classes/ActiveRecord/Attributes/ClassMethods.html
这会导致未定义
我试过添加活动记录属性:
include ActiveRecord::Attributes
Run Code Online (Sandbox Code Playgroud)
作为一个包含但是这会导致与模式相关的不同错误。
如何在无表模型中使用该属性?谢谢。
activerecord attributes ruby-on-rails activemodel ruby-on-rails-5
如果这是一个非常普遍和/或荒谬的问题,请道歉; 我发誓我已多次阅读文档,并且所有内容似乎都专注于ActiveRecord,以至于他们已经离开了除了创建或编辑模型数据之外的其他形式的路径.
例如,带有输入的表单可控制某些统计信息的提取和显示.rails为验证此表单的用户输入提供了什么,不会save
在任何记录上调用?像:
:email
必须是电子邮件地址:num_products
必须是正整数:gender
必须是"M"或"F"之一:temperature
必须在-10到120之间等等(大多数Web框架标准的东西)......
Rails中有什么东西可以让我执行这个任意验证,还有一些查看辅助工具来显示错误列表,还是一切都与ActiveRecord相结合?
道歉,如果我的文档中忽略了这一点,但是这个和这个没有真正覆盖它,至少至于MT疲惫的眼睛可以告诉.
划痕头
感谢Rob的回答,这就是我想出的.我创建了一个实用程序类(恰当地命名Validator
),它只是嵌入到我的控制器中,用于任何需要它的东西.
module MyApp
class Validator
include ActiveModel::Validations
include ActiveModel::Conversion
extend ActiveModel::Naming
def initialize(attributes = {})
super
attributes.each { |n, v| send("#{n}=", v) if respond_to?("#{n}=") }
end
end
end
Run Code Online (Sandbox Code Playgroud)
例如,现在在控制器中,只需定义一个内联类:
class LoginController < ApplicationController
class AuthenticationValidator < MyApp::Validator
attr_accessor :email
attr_accessor :password
validates_presence_of :email, :message => "E-mail is a required field"
validates_presence_of :password, :message => "Password cannot be …
Run Code Online (Sandbox Code Playgroud) activemodel ×10
ruby-on-rails ×10
ruby ×5
validation ×4
activerecord ×3
attributes ×2
controller ×1
forms ×1
rake ×1
simple-form ×1