Enable Coldfusion ORM per component - orm

I've started using ORM in Coldfusion 9, but I'm running into an issue in which I've got a CFC that is set to persistant=true so that when I run myCFC.init() the default values of the properties are assigned - but I don't want to use this CFC with ORM.
The problem is that Coldfusion throws the error "Table myCFC defined for cfc myCFC does not exist."
Is there a way I can get my application to ignore certain CFCs? Or only pay attention to specific CFCs, other than persistant=true
Alternatively, can I get my default property values to take effect without making the component persistent

Alternatively, can I get my default property values to take effect without making the component persistent?
Yes, just set them in your init() method.
<cfcomponent name="person" persistent="false" output="false">
<cfproperty name="gender"><!--- Non-persistent CFC: you can't set a default here --->
<cffunction name="init" output="false>
<cfset variables.gender = "m"><!--- Set the default here --->
</cffunction>
</cfcomponent>
You would also need to do this in your persistent CFCs for any complex or dynamic value defaults (e.g. an array or the current date), since you can only set simple default values (e.g. a literal string or integer) in property declarations.
<cfcomponent name="person" persistent="true" table="persons" output="false">
<cfproperty name="gender" default="m"><!---Persistent CFC, so this simple default will be set --->
<cfproperty name="dateCreated"><!---You can't set a default dynamic date value --->
<cffunction name="init" output="false>
<cfset variables.dateCreated= Now()><!--- Set the current datetime here --->
</cffunction>
</cfcomponent>

Any code you place between your opening and the first will be executed. I'm assuming your using CFproperty tags to set you defaults. Instead, use this structure:
<cfcomponent name="aCFC">
<!---
|| Psuedo Constructor code: this code runs when the object is created.
||--->
<cfset defaultVar_1 = "default value">
...etc
<cffunction name="firstFunction">
...
</cffunction>
</cfcomponent>

Related

How to re-trigger the default error screen from the onError function in application.cfc using ColdFusion 11?

I use the onError function inside Application.cfc to integrate with RayGun when the code is on live but when we are on dev I'd like to be able to revert back to the normal ColdFusion error event. At the moment I have some basic error handling in place but it isn't as good as the default ColdFusion behavior. Does anybody know if this is possible and how?
I intend to add this as a feature request for ColdFusion 12 if there is no way of doing it.
This works when I run it.
in Application.cfc
<cffunction name="onError" access="public" returntype="void">
<cfargument name="Exception" required=true type="any">
<cfif true>
<cfthrow object="#arguments.exception#">
<cfelse>
error
</cfif>
</cffunction>
in cfm page.
<cfscript>
X=Y; // Y is undefined
</cfscript>
All you have to do is replace <cfif true> with something that identifies your development environment.

Bean data doesn't write to table via ORM/entityLoad()

I'm trying to implement CF10 ORM to a current project but there seems to be a problem between my DAO and my table (11g).
I pass in a bean in the call to this DAO method:
<cffunction name="saveData" access="public" returntype="void">
<cfargument name="DataBean" />
<cfset entitySave(arguments.DataBean)/>
</cffunction>
This should write it to the table. If I dump the arguments from inside this method the bean is populated, but nothing writes. There's no errors being thrown so nothing immediately obvious.
Can anyone tell me where I might be going wrong?

CFWheels - How do I increment a number in a database column?

Just wondering, with CFWheels ORM, how I go about incrementing a number in a column?
In straight up SQL I would do something like:
UPDATE table
SET field = field + 1
WHERE ...
I'd like to avoid "fetching" the value from the column and incrementing it manually. I'll be doing a lot of this in my app, so it's an overhead I could do without (plus I'd also like to keep my code simple and elegant).
Could something like this work?
<cfset post = model("post").findByKey(99) />
<cfset post.update( myColumn = myColumn + 1 ) />
Appreciate some input.
You can abstract this in the base Model.cfc if you need to repeat it a lot:
<cfcomponent extends="Wheels">
<cffunction name="incrementColumn" returntype="boolean">
<cfargument name="key" type="string" required="true">
<cfargument name="property" type="string" required="true">
<cfset local.record = this.findByKey(arguments.key)>
<cfset local.record[arguments.property]++>
<cfreturn local.record.update()>
</cffunction>
</cfcomponent>
Then you can call it from your controller like so:
<cfif post = model("post").incrementColumn(params.key, "myColumn")>
Success
<cfelse>
Error
</cfif>
the orm in cfwheels doesn't support this. for stuff like that straight sql is the way to go. the best thing to do is to create a custom method on you model to encapsulate the logic.

cfqueryparam questions/help

Via this question I've been told to start using cfqueryparam for my data, to prevent SQL injection attacks.
How do I use it for my forms? Right now I've been going over Ben Forta's book, Vol 1 and been passing data to my form, then to a form processor that calls a CFC. The CFC takes them in as a cfargument then injects that into the database with any type="x" validation.
Io use the cfqueryparam, I use that on the query itself and not even declare cfargument?
You can still use a CFC, but remember that string data passed as a function argument will still need <cfqueryparam>. Here is an example:
<cffunction name="saveData" access="public" returntype="void" output="false">
<cfargument name="formVar" type="string" required="true" />
<cfquery name="LOCAL.qSave" datasource="myDSN">
insert into myTable (col1)
values (<cfqueryparam cfsqltype="cf_sql_varchar" value="#ARGUMENTS.formVar#" />)
</cfquery>
</cffunction>
The important habit to get into is to always use <cfqueryparam>, even in CFCs.
Here is some more info on those edge-cases where you might find it hard to use <cfqueryparam>.
Hope that helps!

ColdFusion: How to insert numbers( having a 'comma'(,)/ currently iserted as 0) from form fields into the database

A form field value like 45,234 is to be inserted into the DB as 45234. When I try to do insert for 45,234, all it gets into the DB is 0.Note:- I am able to insert 45.234as 45.234 in the SQL DB.
The form field is named costOfShares, which is to be inserted into the table ShareVales (SQL Server 2005). I am using CF8.
SQL
table:-ShareVales; field:-costOfShares; DataType:-float
ColdFusion (form page)
<li>
<cfinput size="8" maxlength="20" name="costOfShares"
id="costOfShares" value="#share.GetcostOfShares()#">
</li>
Share.cfc:-
<cfcomponent>
<cfscript> Variables.CostOfShare </cfscript>
<cffunction name="GetCostOfShare" returntype="numeric" access="public" output="false">
<cfscript> variables.CostOfShare; </cfscript>
</cffunction>
<cffunction name="SetCostOfShare" retuntype="void" access="public" output="false">
<cfargument name="costOfShare" type="string" required="true">
<cfscript> variables. costOfShare = arguments. costOfShare; </cfscript>
</cffunction>
</cfcomponent>
ColdFusion (query page)
<cffunction>
<cfargumnet>
<cfquery …>
INSERT INTO ShareVales(shareUnitId, costOfShares)
VALUES (
<cfqueryparam cfsqltype="cf_sql_integer"
value="#arguments.share.GetshareUnitId()#">,
<cfqueryparam cfsqltype="cf_sql_float"
value="#arguments.share.GetcostOfShares()#">);
</cfquery>
</cffunction>
When I use the following directly in the Query Editor:
INSERT into share(setCostOfShare)
values(Cast(replace('5,322,444',',','') as float))
it succeeds. The error is while using cfquery/cfqueryparam in the ColdFusion template.
So, how do insert the 45234 when the form field costOfShares contains a value with commas?
If they type a comma, strip it out first before trying to insert.
LSParseNumber("45,234", "French (standard)")
Or if "French (standard)" is already your system standard system default locale, just use:
LSParseNumber("45,234")
Or...
<cfset setLocale("French (standard)")>
<cfset value = LSParseNumber("45,234")>
They'll return 45.234 (if you want 45234 instead, use US locale, see doc!)
I'd suggest you to store costOfShares as a valid ColdFusion numeric value (aka, use '.' instead of
','), and only use LSNumberFormat() or LSLSCurrencyFormat() to display the value on the view. That way you don't even have to LSParse the number, unless the number is created by the user, and he uses ','.
presumably the datatype is a float or something. comma's are not valid characters in a float (unless for European locales). You probably want instead to get the value out of the DB with a comma (but not necessarily store it with one). That would probably mean using the COVERT function during a SELECT:
http://technet.microsoft.com/en-us/library/ms174450.aspx
Not sure if this will help or not, but just put the replace inside of cfqueryparam. That way it hands SQL Server the "already cleaned up version".
CAST(<cfqueryparam cfsqltype="cf_sql_float"
value="#REPLACE(arguments.share.GetcostOfShares()',',','')#"> AS FLOAT)
Or, have CF run a replace on the variable and clean it up before you even try the query.
Or, have CF run a replace on the variable and clean it up before you even pass it in as an argument.