1

Good Day.

I have a problem with my Model named "Type". The error is:

undefined method `all' for ActiveRecord::AttributeMethods::Serialization::Type:Class

In this particular part of validation:

validates :type_id, presence: { message: 'selected is invalid' }, inclusion: { in: 1..Type.all.count }

Maybe it's due to reserved names conflict in Rails. But is there a way that Rails will consider this name before I proceed to refactor? (if nothing else to do).

It's really a bad choice for a name but it's too late.

PS.

When I do 'Type.all.count' in rails console, there are no errors that occured.

Charlie
  • 341
  • 3
  • 11
  • why do you want to validate it? i'm assuming it's a FK but then why would you want to validate it? are you letting your user to set it? and Type is a `reserve` word anyways – Mandeep Jun 22 '14 at 15:17
  • `Type` is reserved one in Rails.. DON'T use it..; Change your model name.. – Arup Rakshit Jun 22 '14 at 15:17
  • @user2675613 No, it will be populated on select tag but the administrator can add more values to that table. I opt to validate it 'cause I think the items in select tag can be manipulated using Javascript on the client side, and maybe I'm just too paranoid :). – Charlie Jun 22 '14 at 15:26
  • @ArupRakshit rename is my last resort if there's nothing that can be done about the problem. – Charlie Jun 22 '14 at 15:28

3 Answers3

3

Here is a list of reserved words in Rails. As you can see, type has also been reported to cause problems.

Rails is built over convention over configuration agreement, so I would suggest just to pick another model name (which is not mentioned in stated blog post).

Take a look at this thread to get an idea of what should be done to turn your Type model to something else.

In case you are completely sure model name is not the case, you could try to trick around with different validation notations like

inclusion: { in: 1.upto(Type.all.count).to_a}

Community
  • 1
  • 1
twonegatives
  • 3,400
  • 19
  • 30
  • Due to my negligence, I'm aware that type is a reserved word. I used to have column named 'type' in my table and got problem with it, that's made aware of reserved words. But when I tried to used it in Model name, I never had a problem, but just then (stupid me). I just don't like two words to describe a name for my Model, example document_type, account_type. If nothing else we can do about it, I am ready for Migration and Refactor. – Charlie Jun 22 '14 at 15:36
  • But when I do 'Type.all.count' in rails console, there are no errors that occured. – Charlie Jun 22 '14 at 16:14
  • 1
    @Charlie In case you are completely sure model name is not the case, you should provide more code from `Type` model. Also you could try to trick around with different validation notations like `inclusion: { in: 1.upto(Type.all.count).to_a}`. – twonegatives Jun 22 '14 at 16:20
  • thank you! that `1.upto` really helped me. I'll post my answer. Fortunately, I found a workaround. – Charlie Jun 22 '14 at 16:40
0

Ruby's constant lookup is resulting in it finding the "wrong" Type class. Using "::Type" forces ruby to use the top level Type constant.

You should note that this count will be done once only: when the rails instance starts. If new types were to be added, the validation would not take that into account. If a type were ever deleted then it would not allow the last type to be used.

If you have a type association then you could do

validates_presence_of :type

Upon saving it would try and load the corresponding Type object from the database, so saving would fail if there was no such row.

For a really strong guarantee, you could use a foreign key constraint (the foreigner gem adds helpers to rails migrations for this, but you can also just write the sql statement by hand)

Frederick Cheung
  • 83,189
  • 8
  • 152
  • 174
  • The problem is the Model itself not the column. Anyway, thanks for your response. – Charlie Jun 22 '14 at 17:16
  • 1
    I know. That's why I suggested ::Type.all.count. I was pointing out that this way of validating type_id has its flaws and pointed out some alternatives – Frederick Cheung Jun 22 '14 at 17:44
  • You are so good man! Sorry for the misconception, `::` did the trick! Finally we've got the real solution here. Yes! – Charlie Jun 22 '14 at 18:09
  • By the way, is `validates_presence_of :type` the proper way of validation instead of `inclusion: {...}`? – Charlie Jun 22 '14 at 18:18
  • In general there not the same thing no, but here it's a reasonable fit since what you care about is that it is possible to load a Type for that id – Frederick Cheung Jun 22 '14 at 19:55
  • It was a good suggestion! I also found out that it is more appropriate validation to use. Actually, I already implemented it last night :) – Charlie Jun 23 '14 at 04:56
0

Fortunately, I found a workaround. However, it is not recommended but if you don't want to do Migration and ton's of Refractions, here is my solution (credits to twonegatives).

in my validation code:

inclusion: { in: 1.upto(:type_alias) }

then create that method

type_alias
def type_alias
  Type.all.count
end
Community
  • 1
  • 1
Charlie
  • 341
  • 3
  • 11