简体   繁体   English

如何在保存在rails上的ruby之前验证表中的记录

[英]how to validate a record in table before saving in ruby on rails

I am new to Ruby on Rails I have a scenario in which I have a form which has some fields. 我是Ruby on Rails的新手我有一个场景,其中我有一个包含一些字段的表单。 One of the field values I need to validate against a table which has the data . 我需要对具有数据的表进行验证的字段值之一。 I want to restrict the user from saving any data unless the field is validated with the table records. 我想限制用户保存任何数据,除非使用表记录验证该字段。

Initially I added the code in controller to validate that but I have other fields which I need to validate as empty so it did not work . 最初我在控制器中添加了代码以验证它,但我有其他字段需要验证为空,所以它不起作用。

Also I want the the validation error to be part of other errors. 此外,我希望验证错误成为其他错误的一部分。

I tried the below code in the model file 我在模型文件中尝试了以下代码

before_create :validate_company_id

def validate_company_id
    cp = Company.find_by_company_id(self.company)
    if @cp != nil
       return
     else
        self.status ||= "Invalid"    
     end
end

But its not validating , could you help me how I can validate it . 但它没有验证,你能帮助我如何验证它。

regards Surjan 关于Surjan

The guys answered correctly, but provided the other way for solution. 这些家伙回答正确,但提供了解决方案的另一种方式。 You could ask yourself: "Why doesn't my code get executed?" 你可以问自己:“为什么我的代码没有被执行?”

First of all, you have errors in your code - @cp is undefined. 首先,您的代码中存在错误 - @cp未定义。 Also, I don't know what are you trying to achieve with self.status ||= "Invalid" . 另外,我不知道你想用self.status ||= "Invalid"来实现什么。

You also don't have to use self when you're calling an attribute, but you do have to call it when you're assignig a new attribute value. 您在调用属性时也不必使用self ,但在分配新属性值时必须调用它。 So self.company is unnecessary, you can just use company . 所以self.company是不必要的,你可以只使用company

I've also noticed you have the company_id attribute in your companies table. 我还注意到你的companies表中有company_id属性。 That's not neccessary, common convention is using just an id instead. 这不是必要的,常见的惯例是仅使用id。 If you don't want to alter your table you can set the id field on your model like so: 如果您不想更改表格,可以在模型上设置id字段,如下所示:

class Company < ActiveRecord::Base
  set_primary_key :company_id

  # ... the rest of your model code ...
end

After that you can use Company.find instead of Company.find_by_company_id . 之后,您可以使用Company.find而不是Company.find_by_company_id

Okay, let's say you have the following code after the fixes: 好的,假设修复后你有以下代码:

before_create :validate_company_id

def validate_company_id
    cp = Company.find(company)
    if cp != nil
       return
     else
        self.status ||= "Invalid"    
     end
end

First of all I would like to use ternary operator here 首先,我想在这里使用三元运算符

before_create :validate_company_id

def validate_company_id
    Company.find(company) ? return : self.status ||= "Invalid"
end

Isn't this cleaner? 这不是更干净吗? It does the exact same thing. 它完全一样。

Now about that self.status of yours. 现在关于你的self.status If you would like to invalidate the object in ActiveModel you have to set some values in errors hash. 如果您想在ActiveModel对象无效,则必须在errors哈希中设置一些值。 You're in misconception if you think that a model with the status attribute of "Invalid" is invalid. 如果您认为状态属性为“无效”的模型无效,则您会产生误解。 It's still perfectly valid model in Rails. 它仍然是Rails中完全有效的模型。

So how do you invalidate? 那么你如何宣告无效?

You put some values into errors hash. 你把一些值放入errors哈希。 You can also specify a message and the attribute you're validation error refers to. 您还可以指定消息以及您验证错误所引用的属性。

So let's do it on your model 所以让我们在你的模型上做

before_create :validate_company_id

def validate_company_id
    Company.find(company) ? return : errors.add(:company,"Invalid Company ID")
end

Now if you try to save your model with invalid company_id it will still pass and get saved to the DB. 现在,如果您尝试使用无效的company_id保存模型,它仍会传递并保存到数据库中。 Why is that? 这是为什么?

It's because of the ActiveModel s lifecycle. 这是因为ActiveModel的生命周期。 Your method gets called too late. 你的方法被调用太迟了。

Here are all the callback methods you can use 以下是您可以使用的所有回调方法

Creating 创建

before_validation
after_validation
before_save
around_save
before_create
around_create
after_create
after_save

Updating 更新

before_validation
after_validation
before_save
around_save
before_update
around_update
after_update
after_save

Destroying 销毁

before_destroy
around_destroy
after_destroy

Notice how your method gets called long after the validation cycle. 请注意在验证周期后很长时间内如何调用方法。 So you should not use before_create , but after_validation or before_validation callbacks instead. 所以你不应该使用before_create ,而是使用after_validationbefore_validation回调。

And here we are with the working validation method of your model. 在这里,我们使用您的模型的工作验证方法。

after_validation :validate_company_id

def validate_company_id
    Company.find(company) ? return : errors.add(:company,"Invalid Company ID")
end

instead of using before_create. 而不是使用before_create。 You can tell the model to use a custom method for validation as follows 您可以告诉模型使用自定义方法进行验证,如下所示

validate :validate_company_id

def validate_company_id
    cp = Company.find_by_company_id(self.company)
    if cp.nil?
      errors.add(:company, 'Invalid Company ID')
    end
end
Inside you model, you can add custom validations as below:

validate :validate_company_id

def validate_company_id
  Your validations 
  Add error messages can be added as below
  errors.add(:company, "is invalid")
end

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM