Facing an issue in accessing a rails model - ruby-on-rails

My postgres table is having a column name called "class". On accessing the relevant model to this table am getting this error: (Object doesn't support #inspect). This all issue is because of using a reserved word as a column name.
Is there any solution to this to make the model accessible without modifying/renaming the column name of the table? Am using Rails5. Thanks in advance for any suggestions.

I just tested with a column named class, it seems to mess up ActiveRecord's internals somehow. Thus I think you'll need to rename that column to e.g. klass.
Or, in case you can't change DB schema, create an updatable view on top of it, where you name the column as you please.

Related

rename domain class, groovy and grails reverse engineering

How do a rename a domain class while reverse engineering or after reverse engineering.
i generated class using reverse engineering in Groovy and Grails.
the domain class name was AgentTable. I want to rename it as Agent. When i renamed the domain class using IntelliJ (right click - refactor - rename), it renamed the AgentTable to Agent whereever it was used. but when i start the server (run the app), giving error
"nested exception is org.hibernate.HibernateException: Missing table: agent"
I have to do this for few domain class. is it anyway i can give an alternative name while reverse engineering the domain classes.
or after domain class was created how do i rename it without this error.
Look into your database the name of the table it created for the agent. Once you know the name of the table add the following in your new domain
static mapping = {
table "table-name-here"
}
While it works I would not recommend #elixir 's approach.
In my opinion the mapping is not supposed to be used for renames. This is also how I understand the official documentation.
In the example they use it to map Person onto the 'people' table, not because of a rename but because of a semantic reason. Tables are typically named after the plural form. Here is a nice answer on another question regarding this. In the project I am working on the domain object 'User' is mapped to the table 'users'. You can not use the table name 'user' as it is an SQL statement.
Assumptions and clarifications:
In my experience Grails maps the domain name to the table name after these rules (example domain name 'MyExampleDomain':
separate the domain name by capital letters (My Example Domain)
lower case all (my example domain)
replace spaces with underlines (my_example_domain)
Following this your Domain Class 'AgentTable' has a table 'agent_table' in your respective database. After your rename Grails even tells you what it wants:
nested exception is org.hibernate.HibernateException: Missing table: agent
It wants to look up values in a table called 'agent' but it can not find it. The refactor function of IntelliJ does not rename the functions, so it will miss out on the database.
Luckily we know exactly what values it wants - the values previously found in 'agent_table'.
So why create this confusion with remapping domains and table names when we could just rename the table and be done with it?
The solution:
Execute an SQL script like this on your database:
ALTER TABLE <old_domain_name> RENAME TO <new_domain_name>;
The names are of course in their "table-form".
This simply renames your table to match the expected format in Grails. When restarting everything should be fine.
However you do not need to use rename. You could also create a whole new table, build it the way the domain objects wants it to be and then migrate the data. See section 'Problems with this approach' for information on when to use what.
Problems with this approach:
As always, tinkering with information a program depends on (and even generated itself) will often have some dire consequences if you aren't careful.
For example we have to pay attention to keys. If your domain object has a relation to other objects it will hold them in the table via foreign keys. Depending on how you chose to migrate the information in the table you might have deleted these foreign keys connections. You will have to add them via a separate SQL statement. When you choose to recreate the table this will happen for sure. Renaming it should keep the keys.
Another one are column names. If you choose to rename attributes you will also have to rename the columns via SQL. You will also have to remember the foreign keys other tables might have on the table you are renaming. RENAME did this automatically for me, but you should double check.
Why you should still stick with this approach:
Remapping domain objects to the tables with old names is bound to create code smell and confusion. Do you really want to remember these mappings in your head? And more importantly: do you really expect other people to have to work with this?
The best case is if people can't even tell if this object has ever had a different name and changing the database is the best way I know to achieve this.

T4 Template get table name of database

There are times where I want to avoid using the EF because it takes longer to execute. As a result I want to create raw sql queries for performance purposes.
If I do <#=entity.Name#> it will give me the name of my model. For example it returns me Contact. The name of that table in the database is Contacts (note the s at the end). How can I get the actual table name instead of the model name?
I'm not familiar with the EF T4 templates as I don't use them. EF has it's own Pluralization service.
System.Data.Entity.Infrastructure.Pluralization.EnglishPluralizationService
You can create an instance of this class and call Pluralize to get the Pluralized word. Probably not the most EF-pure way, but it will work. Maybe you can as for the EntitySet name or something if this feels dirty to you.

Using ActiveRecord classes with legacy tables

I have many legacy databases from which I need to pull raw data. Each of the tables in the database have arbitrary names, and an arbitrary collection of fields. I have been getting access to these fields with the following class:
class Frt < ActiveRecord::Base
establish_connection :legacy
set_primary_key "point"
end
When I reach the point in my code where I know the table name, I can call:
Frt.set_table_name "table"
t = Frt.find_by_sql("blah")
something = t.field_name + t.other_field_name
etc...
The problem is that I've realized that this locks the accessible field names to whatever table I select first. If I try to change the table with another call to the `set_table_name' method, it changes the attribute for the class, but any new instances will still have the same set of fields as the first one. So far, in my app, I've not needing anything else, but I'm expanding the program in a way in which I know it will bite me in the butt down the road.
I've tried `Frt.send :set_table_name "new_table"', hoping that it would cause ActiveRecord to do it's magic again. It doesn't.
Can anyone suggest how I might be able to keep the convenience of ActiveRecord, but get it to dynamically remap its fields for whatever table I need loaded?
I've never used it, but Magic Model Generator claims to create models for tables automatically.
Sorry to answer my own post, but I guess I didn't explain it very well. In case someone else comes along after this, what I needed to do was issue a call to the "Frt.reset_column_information" method. I was revisiting this issue, and just dumped all the methods on the ActiveRecord class, and found that one lurking in the list.
A better way to solve this would be to create a model for each legacy table you need to interact with - no dynamic table name remapping required, and it works right out of the box.

Facultative relation with Doctrine ORM

How should be implemented facultative one-to-one relation in Doctrine ORM and Symfony? Suppose there are some folders represented in database. Each folder can have a default icon or some custom icon represented in another table. How should this relation be described in the schema file? How can I tell that in case of given folder relation does or doesn't occur?
I myself have to guesses, but each seems to be not quite good:
1) Let's say I define folder_icon table with id column and folder_icon_id column in folder table and link these columns with foreign key. If folder_icon_id contains NULL, relation doesn't occur. If it contains some integer value it points to respective folder icon. When I implement it this way and try to obtain folder icon using something like $folder->getFolderIcon(), I get an instance of FolderIcon class with fields set to null (where I would rather excpect to get something like NULL, FALSE or Doctrine_Null). Why is it so? How should I check if the returned object is not 'real' folder icon?
2) Let's assume that I use method similar to previous but I define first row of folder_icon table to be the default icon, so that each folder that doesn't have any custom icon selected is related to this first row. In this case there is no problem with getting some dummy instances of FolderIcon class. But there is a problem if custom folder icon is removed form database, as there is no onDelete behaviour 'SET 1' to relate any folders using the deleted icon with the default icon.
How should this problem be solved? What is the proper way to define this kind of relation in schema file?
The problem is with the magic methods getVariable
Use $folder->folder_icon and to test for an existence of that relationship use isset(). Have a read of the doctrine website docs about testing for the existence of a relationship, I'm currently mobile so unable to link to it.

ActiveRecord hating a particular column? (Bizarre)

I've been working on a web app lately, and Activerecord has started creeping me out- for the most part it's awesome, but it has taken to treating a particular column like a leper.
Initially I created a student model from a scaffold. The model holds various information like name, email, entry quarter, etc. And that all works beautifully. The problem I'm having is in how it's taken to treating a particular column- a string named type. Type is supposed to have a value like "B.S.", "M.S", "PhD", etc, however, neither creating a new object instance nor editing an old one are able to change the value from ''. Furthermore, if I go into the database and manually change the value, Rails throws a fit and throws errors when I call Student.find.
Any ideas as to what I'm doing wrong?
'type' is a protected column in activerecord for the purpose of inheritance. Oops!

Resources