如何创建Proc以防止轨道模型中的DRY?轨道 5.2.1, rails_admin.


class Client < ApplicationRecord
has_many :projects
validates :name, presence: true
validates :phone,
presence: {
message: "Phone or Email can not be blank",
if: Proc.new { |a| a.email.blank? }
},
length: {
minimum: 10,
unless: Proc.new { |a| a.phone.blank? }
}
validates :email,
uniqueness: {
unless: Proc.new { |a| a.email.blank? }
},
presence: {
message: "Phone/Email can't both be blank",
if: Proc.new { |a| a.phone.blank? }
},
format: {
with: URI::MailTo::EMAIL_REGEXP,
unless: Proc.new { |a| a.email.blank? }
}
def phone_blank?
Proc.new { |a| a.phone.blank? }
end
end

如何创建替换为所有 Propc 的方法? 我刚刚了解了Proc,我还不太熟悉。 我尝试使用 :p hone_blank 替换 if:/unless: 之后的所有 proc,但它无法正常工作。 有人可以告诉我如何制作phone_blank吗?替换代码中嵌入的所有进程的方法工作? 谢谢~

编辑:我忘了提到我正在使用rails_admin作为管理界面。 如果我在 if:/unless: 中调用方法,管理面板将显示找不到模型"客户端">,那么该模型将从管理面板中消失。 我不确定这是一件rails_admin事,或者这就是Rails 5的行为方式。 我对RoR很陌生,仍然对所有不同版本的Rails感到困惑。

对于使用方法,不需要Proc包装器。

例如

class Client < ApplicationRecord
has_many :projects
validates :name, presence: true
validates :phone,
presence: {
message: "Phone or Email can not be blank",
if: email_blank?
},
length: {
minimum: 10,
unless: phone_blank?
}
validates :email,
uniqueness: {
unless: email_blank?
},
presence: {
message: "Phone/Email can't both be blank",
if: phone_blank?
},
format: {
with: URI::MailTo::EMAIL_REGEXP,
unless: email_blank?
}
def phone_blank?
phone.blank?
end
def email_blank?
email.blank?
end
end

此外,您可以直接在验证中指定此条件,而无需将方法或Proc作为字符串。

例如

class Client < ApplicationRecord
has_many :projects
validates :name, presence: true
validates :phone,
presence: {
message: "Phone or Email can not be blank",
if: 'email.blank?'
},
length: {
minimum: 10,
if: 'phone.present?'
}
validates :email,
uniqueness: {
if: 'email.present?'
},
presence: {
message: "Phone/Email can't both be blank",
if: 'phone.blank?'
},
format: {
with: URI::MailTo::EMAIL_REGEXP,
if: 'email.present?'
}
end

你可以编写一个返回lambda的类方法,如下所示:

def self.blank_field?(field)
->(m) { m.send(field).blank? }
end

然后说这样的话:

validates :phone,
presence: {
message: "Phone or Email can not be blank",
if: blank_field?(:email)
},
length: {
minimum: 10,
unless: blank_field?(:phone)
}

请注意,我们使用blank_field?而不是blank?,因为blank?已经被采用并且我们不想覆盖它。而且由于这是一种"内部"方法,因此我们不必担心public_sendsend

不是直接的答案,但 DRY-ing 事物的另一种方法是利用with_options

with_options if: -> { email.blank? } do
validates :phone, presence: { message: "Phone or Email can not be blank" }
end
with_options if: -> { phone.blank? } do
validates :email, presence: { message: "Phone/Email can't both be blank" }
end
with_options if: -> { email.present? } do
validates :phone, length: { minimum: 10 }
validates :email, uniqueness: true, format: { with: URI::MailTo::EMAIL_REGEXP }
end

当验证具有取决于不同条件的条件时,这尤其有用。比如说,类别(如果你有一个category列(,你可以简单地将这些验证分组with_options

琐事:

你可以把-> { ... }想象成你已经熟悉Proc.new { ... }(尽管准确地说这是一个lambda......这就像一种特殊类型的Proc.如果您进一步感兴趣,请参阅这些SO帖子:此处和此处

相关内容

  • 没有找到相关文章

最新更新