I am using mongoid/Rails for my application server. I defined my own field typ 'formula'. This is a field I don't want to have persistent in the database since this is not a data field but a formula which is consistent across all records of a model. So I stored this formula in my metadata and whenever I create dynamically a model where I need this formula I create a field with my custom type 'formula' where the formula is the default value. This works so far - but as soon as I save a record which includes my formula field it doesn't.
So before I create or update any records I want to loop over all fields of my model and depending on the type the field I allow it to be updated - or not ( so for every formla field I don't allow updates)
I can loop over all field names (model.fields.keys.each) and check the name of the field - But I haven't found a method to loop over all fields and access the type. Any idea?
But perhaps there is another way to avoid my formula field is saved in the database? I create a mongoize (object) method for my new field type 'formula' and this method simply returns nil - but this still writes an empty field to the database.
Related
The scenario:
I have a considerable amount of entities as models in CodeFirst mapped to the database fieldname with the Attribute [Column("str")].
I have a bunch of Reporting Service Reports (in local-mode) with the DataSets mapped to the database field names.
I can't pass direct results of linq queries to those reports with the ToList() method because of the field names. What I can do (and I'm trying to avoid) is to type select new for each object; or run each query via a different datasource.
Question:
I would like to know if there is any trick to have a IQueryable object with the original field names instead of the property names. Something like a dynamic select new.
Any suggestions will be appreciated.
No, there isn't. The database column names either have to match the property name, or you have to use the Column attribute to make them line up. That's your only choices.
There might be a group of records in a table where only two fields vary record by record, and rest fields remains same. This calls for a normalization by splitting by a table through a foreign key association. But, in Ruby-on-Rails, it would mean the creation of a model. So, is it still possible to lessen use of disk space?
May be, it is, because it would be reasonable that storing multiple values of one column in a record would require the column to be an array of any type. But declaring the field to be :array type results in an error. So, is there a way to work around it?
After generating a model, open the model's file. Insert one line for each field.
serialize :field_name
But ensure that the fields for which you are serializing, should be of type
:text
or
:string
If they aren't of such primitive data types, i.e. of another type like
:datetime
then it would return an error.
This step is not complete as a whole. You need to do one complementing step: de-serialize, because in the model-level storage, it is stored as a string starting with "---\n-", which is not suitable for array-type operations.
While reading data from the model, you need to perform the following step:
YAML.load(field_name)
where field_name refers to the field that was serialized.
The above step would return an array, on which you can perform normal array operations.
How Could I store integers (user id's ranging from 1 to 9999) serialized in a database column and retrieve them back?
In my User model I have invites column,
User model
serialize: invites
invites = text field
Now I'm trying to do 2 things:
Append the user_id integer (from 1 to 9999) serialized in a column "invites"
Retrieve all the user id's back from the User.invited column ( deserialize it ? )
From the fine manual:
serialize(attr_name, class_name = Object)
If you have an attribute that needs to be saved to the database as an object, and retrieved as the same object, then specify the name of that attribute using this method and it will be handled automatically. The serialization is done through YAML. If class_name is specified, the serialized object must be of that class on retrieval or SerializationTypeMismatch will be raised.
So, if you want to store an array of integers as a serialized object, then:
class User < ActiveRecord::Base
serialize :invites, Array
#...
end
You'd want the invites column to be a text column in the database (not string!) to avoid running into size issues.
Then you can treat user.invites as a plain Array:
user.invites = [ 1, 2, 3 ]
user.invites.push(11)
That of course doesn't verify that that numbers are valid or that you don't have duplicates (but you could use a Set instead of an Array for that), it also won't prevent you from putting a string in there.
I don't recommend that you do this though, serialization is almost always a mistake that will come back to bite you later. A serialized column is an opaque blob of data as far as the database is concerned: you can't update it in-place, you can't query it, all you can do is pull it out of the database and put it back. serialize uses YAML for serialization and that's an awful format if you need to work with your serialized data inside the database; you can also run into interesting encoding issues during upgrades.
You're better off setting up a traditional association table and a separate model (possibly using has_many ... :through =>) to handle this situation.
I have created a form which allows the user to add to an inventory of items, stored in a database. Each item in the Inventory table is associated with a UID which is auto-incrementing, non-editable, and effectively auto-generated.
The top field in the form is ItemID, which has input disabled and is merely there to inform the user of the ID of the new item they are about to add.
Ideally, here's the pseudo-code:
<input type="text" name="email" value="<% (SELECT Max(ItemID) FROM dbo.Inventory).ToInt32 + 1 %>" disabled="disabled"/>
I already have a Linq to SQL ORM set up. This is all being done in MVC, so the idea occurred to me to figure out the correct value inside the form's controller and then just passing it to the view directly.
What would be the cleanest, simplest way to achieve this? I think ideally, the "value" field should be no more than 1 line.
This approach won't work.
If ItemID is auto-incrementing field what components increase its value? Anywhere but the database you will run into trouble. Assuming you do use a database assigned field, when you populate your input field with a value you take the next available value at that time. What happens though if two forms are read and submitted out of order? The Id you populate in your value field will not match up with id the database will assign. So this only would potentially work for a single user at a time.
Best is to let the DB assign the value when you do the actual DB insertion using an identity column and not worry about doing this manually or even trying to predict the id - don't populate the value field this way.
I have a DBGrid with a column based on a lookup field.
How can I set it up so that when a user clicks on the column title, it will sort by that field.
My problem here is that I can't figure out a way to create an index on a lookup field.
I'm using Absolute Database for this, but most things that work with the BDE or TClientDataSet will work with Absolute.
Thanks!
I don't think it is possible to create an index on a lookup field. It is possible to create an index on an internally calculated field of a ClientDataSet though. In the OnCalcFields event handler set its value to the value of the lookup field. And set the visible property of the lookup field to false. Now you can sort on the internally calculated field.
What you could do (especially if the data is readonly, and does not have zillions of rows) is use a ClientDataSet to display data in your grid.
Roughly the steps would be like this:
Load the data from your regular into the ClientDataSet,
add a calculated field to the ClientDataSet that contains the value obtained from the lookup,
then add an index to that calculated
field.
--jeroen
You cannot sort by a lookup field. But you can 'fake' this. Let's suppose that you have the following tables: (PK means Primary Key)
Contacts
ID - Integer (PK)
NAME - Varchar(40)
COUNTRYID - Integer
Countries
ID - Integer (PK)
NAME - Varchar(40)
Then you can have the following query in the dataset which is linked to the TDBGrid:
SELECT C.ID, C.NAME, C.COUNTRYID, CO.NAME
FROM CONTACTS C
JOIN COUNTRIES CO ON C.COUNTRYID=CO.ID
(Not tested but I think that you got the idea)
Also you can put this in a view.
Then you'll display in your TDBGrid (as columns) only the ID, NAME and the desired lookup field which you already have (let's call it COUNTRYLOOK).
When one clicks on the Title Header you can change the query by adding in the 4th line an ORDER BY . For the specific column of the lookup field (COUNTRYLOOK), instead of using the 1:1 mapping you can put in the 4th line of your query ORDER BY CO.NAME. Reopen the query and that's it. In practice is much more simpler than my description here.
DevExpress ExpressQuantumGrid can do it, check it out:
http://www.devexpress.com/products/vcl/exquantumgrid/