我遇到了我认为每个人都会遇到的空值问题:也就是说,有不同种类的空值。它可能表示“空”、“未更改”、“未设置”、“未知”或任何数量的事物。我已经到了需要以某种方式区分它们的地步。
基本上我的程序有一个数据库管理器部分,它从我的程序的另一部分接收一个表示要在数据库中更新的数据的对象,该部分负责验证表单数据并将其转换为所述对象(其中一个几个具有特定预定义属性的不同类)。我需要一些方法来区分该对象中的“null”属性,这意味着“我实际上想要将值 null 存储在数据库中”和不同类型的“null”,这意味着“如果数据库中存在现有值,请不要'改变它“。在这两者中,后者将是迄今为止更常见的情况,但我需要一些方法来考虑前者。
我目前的想法,似乎最适合这种情况,是创建一个新类来表示 null 的每个“类型”,例如 Unchanged 类与 SetToNull 类型或类似的东西。然后我可以将该属性设置为其中一个类的实例。
唯一的问题是我想要一个行为类似于现有 isset() 函数的函数,因为它允许我检查给定属性是否存在以及它是否具有一个简单语句中的实际值(与我的新空类型之一相反)。
我知道我可以做这样的事情:
if (isset($thing->property) && !($thing->property instanceof Unchanged || $thing->property instanceof SetToNull)){
// do whatever
}
但是,这显然不理想,因为它又长又笨重,而且我不想在我的代码库中随处可见。我更喜欢这样的东西:
if (myCustomIsset($thing->property)){
// do whatever
}
但是,isset 似乎不是一个正常的函数;如果属性尚未定义或类似的东西,它会以某种方式抑制警告,所以我不确定如何自己实现类似的东西。
最佳答案
就我个人而言,我不会更改模型。模型应该代表数据库中的数据,并且其属性的值应该与这些属性代表的列的值相同。
我会考虑改变模型获取数据的方式。听起来您正在从表单数据实例化模型,其中不包含每个属性的值,因为表单仅更新某些属性。
如果您通过从数据库中选择它来实例化模型,然后在验证和保存它之前用表单数据修改它,它将具有每个属性的正确值,并且 null 将明确表示 null。
关于php - 在 PHP 中避免空值时,我可以重新实现 isset 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55069505/
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta
查看Ruby的CSV库的文档,我非常确定这是可能且简单的。我只需要使用Ruby删除CSV文件的前三列,但我没有成功运行它。 最佳答案 csv_table=CSV.read(file_path_in,:headers=>true)csv_table.delete("header_name")csv_table.to_csv#=>ThenewCSVinstringformat检查CSV::Table文档:http://ruby-doc.org/stdlib-1.9.2/libdoc/csv/rdoc/CSV/Table.html
鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende
我正在使用active_admin,我在Rails3应用程序的应用程序中有一个目录管理,其中包含模型和页面的声明。时不时地我也有一个类,当那个类有一个常量时,就像这样:classFooBAR="bar"end然后,我在每个必须在我的Rails应用程序中重新加载一些代码的请求中收到此警告:/Users/pupeno/helloworld/app/admin/billing.rb:12:warning:alreadyinitializedconstantBAR知道发生了什么以及如何避免这些警告吗? 最佳答案 在纯Ruby中:classA
我发现ActiveRecord::Base.transaction在复杂方法中非常有效。我想知道是否可以在如下事务中从AWSS3上传/删除文件:S3Object.transactiondo#writeintofiles#raiseanexceptionend引发异常后,每个操作都应在S3上回滚。S3Object这可能吗?? 最佳答案 虽然S3API具有批量删除功能,但它不支持事务,因为每个删除操作都可以独立于其他操作成功/失败。该API不提供任何批量上传功能(通过PUT或POST),因此每个上传操作都是通过一个独立的API调用完成的
我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden
我正在阅读SandiMetz的POODR,并且遇到了一个我不太了解的编码原则。这是代码:classBicycleattr_reader:size,:chain,:tire_sizedefinitialize(args={})@size=args[:size]||1@chain=args[:chain]||2@tire_size=args[:tire_size]||3post_initialize(args)endendclassMountainBike此代码将为其各自的属性输出1,2,3,4,5。我不明白的是查找方法。当一辆山地自行车被实例化时,因为它没有自己的initialize方法
我正在处理旧代码的一部分。beforedoallow_any_instance_of(SportRateManager).toreceive(:create).and_return(true)endRubocop错误如下:Avoidstubbingusing'allow_any_instance_of'我读到了RuboCop::RSpec:AnyInstance我试着像下面那样改变它。由此beforedoallow_any_instance_of(SportRateManager).toreceive(:create).and_return(true)end对此:let(:sport_
我们的git存储库中目前有一个Gemfile。但是,有一个gem我只在我的环境中本地使用(我的团队不使用它)。为了使用它,我必须将它添加到我们的Gemfile中,但每次我checkout到我们的master/dev主分支时,由于与跟踪的gemfile冲突,我必须删除它。我想要的是类似Gemfile.local的东西,它将继承从Gemfile导入的gems,但也允许在那里导入新的gems以供使用只有我的机器。此文件将在.gitignore中被忽略。这可能吗? 最佳答案 设置BUNDLE_GEMFILE环境变量:BUNDLE_GEMFI