Note that there are some explanatory texts on larger screens.

plurals
  1. POUsing the request scope to store an object
    primarykey
    data
    text
    <p>I'm using <a href="http://www.cfwheels.org" rel="nofollow">CFWheels</a> to develope an application in ColdFusion.</p> <p>I have a model called <code>Vote.cfc</code>. Before a Vote object can be created, updated, or deleted, I need to fetch a post object from another model: <code>Post.cfc</code>. A Vote belongs to a Post. A post has many votes.</p> <p>Using data from the <code>post</code> object, I need <code>to validate the vote</code> object across multiple criteria and several functions. The only way I can think of persisting the post object so that it's available to those functions is by storing it in the request scope.</p> <p>Others have said this is bad practice. But I was not able find out why. I thought the request scope was thread safe, and it would make sense to use it in this situation. </p> <p>My other alternative is to load a new instance of the post object in every function that requires it. Although Wheels uses caching, doing this caused request times to spike by 250%.</p> <h2>UPDATE</h2> <p>Here's some samples. First, the controller handles looking to see if a vote object already exists. If it does, it deletes it, if it does not, it creates it. The controller function is essentially a toggle function. </p> <p><strong>Votes.cfc Controller</strong></p> <pre><code> private void function toggleVote(required numeric postId, required numeric userId) { // First, we look for any existing vote like = model("voteLike").findOneByPostIdAndUserId(values="#arguments.postId#,#arguments.userId#"); // If no vote exists we create one if (! IsObject(like)) { like = model("voteLike").new(userId=arguments.userId, postId=arguments.postId); } else { like.delete() } } </code></pre> <p><strong>Model VoteLike.cfc</strong></p> <p>After that, a callback registered in the model fires before validation. It calls a function that retrieves the post object the vote will belong to. The function getPost() stores the post in the request scope. It is now made available to a bunch of validation functions in the model. </p> <pre><code>// Load post before Validation via callback in the Constructor beforeValidation("getPost"); private function getPost() { // this.postId will reference the post that the vote belongs to request.post = model("post").findByKey(this.postId); } // Validation function example private void function validatesIsNotOwnVote() { if (this.userId == request.post.userId) { // addError(message="You can't like your own post."); } } </code></pre> <p>The alternative to the getPost() function is to use a scoped call "<code>this.post().userId</code>" to get the post object, as such:</p> <pre><code>private void function validatesIsNotOwnVote() { if (this.userId == this.post().userId) { addError(message="can't vote on your own post") } } </code></pre> <p>But I would then have to repeat this scoped call <code>this.post().userId</code> for EVERY function, which is what I think is slowing down the request!</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload