Rails 5.1.2 - Single Table Inheritance: No migration is getting generated - postgresql

I am trying to generate scaffolding for STI implementation. I issue the following.
rails g scaffold user1 type name email
rails g scaffold member company subscription --parent user1
Every thing gets generated file except for the migration file my 'member' model.
When I try to create a member record like this
Member.create(name: "My Name", email: "myname#example.com",
company: 'Example LLC', subscription: 'Monthly Gold' )
I get this error:
ActiveModel::UnknownAttributeError: unknown attribute 'company' for Member. from (irb):1
Any ideas on what is going on?
I use rails 5 and db is postgres

The --parent option assumes that you are already all setup for single table inheritance, i.e. the parent class has a table with a type column (or whatever column you are using for this).
Since the model will be stored in the parent's table, there is no need to create a new table for the subclass, hence no migration
I got this answer similar to this question asked by someone.

To my understanding, you are on the wrong track. In single table inheritance, all the attributes must be present in the parent model table with an additional column name 'type' to indicate the type of inherited model. The column name 'type' can be changed with appropriate settings but ActiveRecord by default looks for 'type' column. You are getting 'UnknownAttributeError' error cause the parent model does not have the following column in its table. You need to write a migration to add the new columns. Hope you understand the concept of STI. For further exploration, I am providing you the link of the official guide. Hope your problem will be solved.
http://edgeguides.rubyonrails.org/association_basics.html#single-table-inheritance

Related

Dynamically Selecting Data from Table in Entity Framework

I know this question might have been asked before but I have not found a single answer yet.
Basically I am using entity framework and I am in need of selecting data from a database without knowing the name of the table, as this will be generic.
Now if I do not know the table name, I do not know the type too as I have tried using context.Database.SQLQuery or context.Database.ExecuteSQLStatement but these all require the type of the object it should be expecting.
All I am receiving as parameters are the name of the table and the row ID.
Could anybody give me further advice?
Thanks.
#
Edit:
I have just been notified that the only property I would need from this table is the Name field...

Why does Entity Framework insist on renaming columns?

Step 1: import code first from existing database. Existing database has a table with the same name as column.
Step 2: in this scenario, Entity Framework sticks a "1" in front of column name in code.
Step 3: when I try to rename it "by getting rid of 1 in front", I get error
member names cannot be the same as their enclosing type
Why is this limitation on EF and is there a solution that doesn't ruin the database in future migrations (by having that column renamed)?
Being forced to use Column1 just seems really terrible and arbitrary.
Thanks.
As pointed out by #shf301 you cant have a property named the same as the class its in, this is a .NET restriction.
However you can name your column anything else and then tell EF to point to your specific column in the database
eg:
[Column("MyColumn")] // "MyColumn" will be what EF expects in the db
public int FlyingMonkies {get;set;}

Table Splitting / Optional Relationship

Currently, I have the following in my code:
modelBuilder.Entity<Client>().HasRequired(e => e.Logo).WithRequiredPrincipal();
This relationship definition is used for table splitting the Logo column (which is VARBINARY(MAX)) into a separate entity. Everything works as expected.
I have chosen to make the Logo column nullable in the database. I tried updating the code listed above to:
modelBuilder.Entity<Client>().HasOptional(e => e.Logo).WithOptionalPrincipal();
When I run the code, I receive the following message:
Additional information: The entity types 'ClientLogo' and 'Client' cannot share table 'clients' because they are not in the same type hierarchy or do not have a valid one to one foreign key relationship with matching primary keys between them.
The problem is that I am not entirely sure what this message is trying to tell me. Why does it work when the Logo column is non-nullable but does not work when it is not? Am I mapping the relationship incorrectly?
Even if the Logo column is optional, the entity relationship between ClientLogo and Client needs to remain the same, it's the property itself that needs to be nullable:
// This should stay the same
modelBuilder.Entity<Client>().HasRequired(e => e.Logo).WithRequiredPrincipal();
// If you used to have a line like this or a [Required] attribute, then it needs to be removed
// modelBuilder.Entity<ClientLogo>().Property(t => t.Logo).IsRequired();

Web API Entity Framework error - Item with idenity already exists in the metadata collection

I am experimenting with a Web API 2 project in Visual Studio 2012. I used the code first from existing DB option with EF6 to select one table and one view. I then tried to create a controller for the simple table using the profile for Web API 2 OData. The scaffolding of the controller fails telling me that "the item with identity 'Client Last Reveiwed On' already exists in the metadata collection". The problem is not only am I sure that field is unique for this project but that field is part of the view and not the table. Below is the model generated for the simple table (t_Client) that I was trying to create the controller for. As you can see the offending column is not part of the class. I will add below the definition for the column that VS/EF doesn't like which is in the class for the view.
Any ideas why this won't work?
Partial Public Class t_Client
<Key>
<DatabaseGenerated(DatabaseGeneratedOption.None)>
Public Property ClientID As Integer
<Required>
<StringLength(255)>
Public Property ClientName As String
Public Property isActive As Boolean
End Class
Here is the column that is defined in a separate view.
<Column("Client Last Reviewed On", TypeName:="date")>
Public Property Client_Last_Reviewed_On As Date?
I am not sure which of these steps fixed the issue but here are some notes on the topic.
Removing references to the model based on the SQL view eliminated errors.
I went into SQL and updated the view to contain a row number column.
Even with the row number column, EF tagged multiple columns as the key.
I manually edited the model to make the row number column the key.
I also had to update a cast the data type of a few columns in the SQL view to match reality, mainly bigint that was really just integer.
My guess is the fix was the well defined key.

DBIx::Class virtual column?

I am building an app with a DBIx::Class (Loader) based ORM. Most of my database models have a 'name' column. One of my controllers searches all schema classes using primarily the 'name' column. A couple of schema classes however don't have a 'name' column.
Is it possible in DBIx::Class to add a sort of 'virtual' column that uses another column instead:
$resultset('Account')->search({name => 'foobar'})
secretly rewrites to
$resultset('Account')->search({accountnumber => 'foobar'})
I hope I am making sense, anyone?
Thx,
Rob
As far as I know this is not possible - not as a key in a search query anyhow. What you could do is create a base-class for all your resultset classes (you are using load_namespaces, right?) which has a method find_by_name or similar, that performs this search on the correct column. The column could default to name but be overridden by a class attribute - which you can set up with mk_accessor.
You can set this base-class to be the default resultset class for all your resultsets with the default_resultset_class attribute of load_namespaces