Rails 3 best practice to modify a boolean attribute? - ruby-on-rails-3

What is the best practice to switch a boolean attribute e.g., un-/publish an article?
For the Model side, I saw Object.update_attribute(:only_one_field, 'my_value') is best for this job, instead of update_attributes.
What about
the View (use a link, a submit button in a form, other ideas?) and
the Controller side?

Views usually use forms for updating models. The form_for helper makes this pretty straightforward.
If you are using a standard update action (your controller inherits from InheritedResources::Base) then your update! method in your controller should handle this fine.
I would actually advise against using Model.update_attribute(:published, value) unless you are aware that this call bypasses your model's validations. This is generally why forms just post to the update or create methods in the controller - those by default go through the entire ActiveRecord lifecycle, calling your validations as well. If you have a reason to bypass them, then by all means use update_attribute.

Related

What is the correct way to use authorization policy class to authorize access to an index page in cakephp4?

I developed a few cakephp3 apps, and now I'm learning how to use cakephp4. I'm trying to centralize all my authorization logic in the *Policy classes. I have a situation where a user wants to access a entity/index page, and I want to validate if he can access this index page by doing some queries.
So right now I'm using $this->Authorization->authorize($this->Entity->newEmptyEntity()); in the controller, in order to be able to access an EntityPolicy->canIndex() method. Is there a more elegant way to do it, to call a policy method without an instance of the entity?
After that, in order to be able to run my queries, I'm using the ModelAwareTrait in the class, and querying data in a similar way that I do in controllers. Is there a better approach?
Send the entity itself. For example, if you are using the Articles controller
$this->Authorization->authorize($this->Articles);
$this->Authorization->can($this->Articles,'index')
While declaring the canIndex() method normally in your Policy.
My solution was somewhat different (and easier I guess)
//In my ProjectController.php
public function index()
{
$project = new Project();
$this->Authorization->authorize($project);
}
this way I don't have to do a useless query (I just create an empty Project object), but at the same time I can check the user attributes.
In my case the solution proposed by #eos (above) didn't work, because calling
$this->Authorization->authorize($this->Projects);
lead to an unwanted result.

IControllerFactory.CreateController gets called for every controller in every request

I'm having an issue that, while not critical, still called my attention.
I happen to have an MVC4 web application where I've replaced the default controller factory for one implemented by myself, within this factory I use unity to inject the constructor parameters for the controller.
What I don't understand is why, for each and every request I make, the CreateController method gets called for every controller in the application and not just the one in the url and the ones called by partial views.
Is that behaviour normal? Is it necessary or is there a way to prevent it?
I see no reason for this and my research hasn't lead me to any good answer.
Thanks!
Ha! It turns out that when you use mvc sitemap solution it builds every controller for every request, by removing this line, that weird behaviour didn't happen anymore
#Html.MvcSiteMap().SiteMapPath()
Thanks anyway for the ones who read this and I hope someone finds this useful!

Spine.js have updateAttributes include new attributes

It seems that Spine's Model.updateAttributes only updates attributes, and does not create new ones in case you supply any.
In my usecase, I have a controller that creates part of the attributes. Then through an Ajax request the server responds with the full object, and I want to update the model instance living in Spine with the additional variables.
For example, I have a model with attributes: name, date_created. Through the controller a user instantiates an object providing only the name. An Ajax request notifies the server which in turn responds with a name and a date_created. This date_created should then be added to the user's model.
Model.updateAttributes doesn't work, and I wouldn't be too fond of deleting the object and creating a new one - that just seems as too much overhead. I could provide default values for variables that are not set upon creation, but that also has a negative side. I guess what I'm looking for is a method that could be called Model.createOrUpdateAttributes. Can anybody recommend a way to achieve this? Thanks!
I might haven't fully understood your usecase, but I'll try to answer.
You need to declare whatever attributes a type of a model has with the configure class method. This declaration helps various model function to do their job later.
After you declare all the attributes you need, you can create model instances with any of the previously declared attributes.
You don't have to provide values for all the declared attributes.
After the ajax call returns, the date_created will be set on your model instance. Until this happens it will be just undefined.
If this solution still can't work for you, please describe why, and I'll gladly try to help.

YII how to call a function?

I'm in need of knowing how to call a PGSQL db stored procedure REQUIRING PARAMETERS
from a yii controller and passing it the parameters. Could please any one provide
me (maybe also the community) with a short tutorial including code snippets
about how to deal with this situation or direct me to sources where I can get the
information related to this topic from?
Thx in advance.
Are you trying to call the function from another controller?
In standard yii installation all controllers extend the Controller class as a base class. Therefore you can put the function in there and it will be accessible to all controllers.
protected/components/Controller.php
Or you could attach function by creating a behaviour:
http://www.yiiframework.com/doc/guide/1.1/en/basics.component#component-behavior

cancan: getting past undefined method `find' for Userhome:Class

cancan did not work with a controller that did not have a class. So I created the userhome.rb model:
class Userhome
end
There is an action in the userhome controller that accesses a page in another directory/class. An attempt to access it yields the following error:
undefined method `find' for Userhome:Class
Is the best thing for me to do...:
delete the userhome model, and
remove "load_and_authorize_resource" from the userhome controller, and
just lock the application down with cancan in every other area possible?
Or is there a workaround to deal with this error?
Take a look at the CanCan documentation on non-RESTful controllers.
A "resource" is the "thing" that your controller is responsible for listing, creating, updating, etc. It often is a model, but need not be (e.g. you might have a "search results" resource that doesn't have a corresponding model).
If your controller really isn't dealing with a resource, then you may want to just use authorize! as appropriate within the controller, but if the controller is dealing with a resource but there is no corresponding model (which sounds like it may describe your situation) then you may want to use authorize_resource and specify that there is no corresponding class. This lets you "pretend" that you have a resource (i.e. you can specify abilities based on actions on a resource) without actually having a model that represents that resource.