This is a Rails newbie question:
When I call create()
on a model, does it bypass the associated controller create
action?
For example, this isn't hitting my tags controller #create action:
user.tags.create(:content => new_tag)
But if I POST to the tags#create
route from a form then it works just fine.
I assumed that calling user.tags.create
would call th开发者_如何学JAVAe controller action and always run the code in it upon create, but apparently it's only during a POST to that route.
What am I missing here?
Edit:
Is there a way to make that call then to ensure the controller create code is run? I have some code to find a tag by permalink and create a new one if necessary, else re-use an existing one. Using model.create() isn't running any of that code. I could be "doing it wrong" though :P
The model knows nothing about the controller, it is simply an object representing state stored in the database, possibly with some additional encapsulated behaviors. The controller is an object that responds to requests made to your server. While the default scaffolding will modify your model, controllers do not have to even use a model.
Controllers and Models are disconnected, but only logically related classes.
If you have code that you want available to all users of your model, then add a method to your model. Then invoke that method from your controller, and anywhere else you'd like that behavior.
Rails works on the MVC design pattern. M is Model which are typically ORM classes. In Rails ActiveRecord is the default ORM and each model maps to a table in the database. This is where the meat of your logic should be. Models know nothing about the larger world from where they are invoked from for e.g. The internet or a web page or a Controller.
Controller forms the C of the MVC. These are your web-applications end-points. Each time a URL is invoked from the browser, it ends up on a controller endpoint. The controller's action "create" is an endpoint. This method is more commonly called an "action". The controller "create" action's job should be to orchestrate the creation of objects, handling and packaging of errors and then redirecting to another location or sending an response back using the Views.
View forms the V of the MVC. Dont want to delve into the V, since it's not pertinent to your question and i assume you know it already.
Thus your Model's "create" method made available by ActiveRecord is significantly different from the Controller's "create" action. The create action in the Controller may invoke the create method on a model as a part of its orchestration.
It is a well accepted practice to keep "Controllers Skinny" and keep "Models Fat". Ensure that your controller action is kept down to not more than a few lines (5-6 lines for a create action typically). The chunk of your program logic must be in the Model itself.
Do not look to have the controller "create" action be invoked when you call user.tags.create. Only web browser requests go to the controller.
user.tags.create
calls the ActiveRecord#create
method inherited into Tags
, which is what the TagsController#create
provides a we accessible front end to.
ActiveRecord#create
creates a new model object and then saves it, nothing to do with the view or controller,
Controller#create
probably calls the model create, if the permissions are right, the parameters are etc, but it does it as a response to a POST from the web end
basically the model and controller are two separate entities and interact through their methods
read more about the MVC methodology
You are correct. ModelClass#create has exactly nothing to do with the controller.
The job of the controller is to respond to an input or "action," do whatever model-related stuff needs to be done, and then otherwise set the scene for a view (selected by the controller method/action) to display details.
At a high level, a model's job is to encapsulate data and, in the case of ActiveRecord-based models, mediate data transfer between memory-based data structures ("models") and the underlying persistent store (database).
Based on your edit, it sounds to me like you want to run your Tags#create method so that some data-related work gets done. This would be more appropriately done in the model IMO, since it sounds like you're doing strictly data-related stuff and don't need the full "MVC cycle" involved with calling a controller method. Can you accomplish what you're looking to do in a before_create callback on your ModelClass? Look here for more info about ActiveRecord callbacks (including before_create).
精彩评论