Rails .create() 与controller#create
这是一个 Rails 新手问题:
当我在模型上调用 create()
时,它会绕过关联的控制器 create
操作吗?
例如,这不会触发我的标签控制器 #create 操作:
user.tags.create(:content => new_tag)
但是如果我从表单 POST 到 tags#create
路由,那么它就可以正常工作。
我假设调用 user.tags.create
会调用控制器操作并始终在创建时运行其中的代码,但显然它仅在该路由的 POST 期间。
我在这里缺少什么?
编辑:
有没有办法进行该调用以确保控制器创建代码运行?我有一些代码可以通过永久链接查找标签,并在必要时创建一个新标签,否则重新使用现有标签。使用 model.create() 不会运行任何该代码。不过我可能“做错了”:P
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 the 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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
该模型对控制器一无所知,它只是一个表示存储在数据库中的状态的对象,可能还具有一些附加的封装行为。控制器是一个响应向服务器发出的请求的对象。虽然默认的脚手架会修改您的模型,但控制器甚至不必使用模型。
控制器和模型是断开连接的,但只是逻辑上相关的类。
如果您希望模型的所有用户都可以使用您的代码,请向您的模型添加一个方法。然后从您的控制器以及您想要该行为的任何其他地方调用该方法。
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 采用 MVC 设计模式。
M 是模型,通常是 ORM 类。在 Rails 中,ActiveRecord 是默认的 ORM,每个模型都映射到数据库中的一个表。这就是你逻辑的核心所在。模型对调用它们的更大世界一无所知,例如互联网、网页或控制器。
控制器构成了 MVC 的 C。这些是您的网络应用程序端点。每次从浏览器调用 URL 时,它都会到达控制器端点。控制器的操作“创建”是一个端点。此方法通常称为“操作”。控制器“创建”操作的工作应该是协调对象的创建、错误的处理和打包,然后重定向到另一个位置或使用视图发送回响应。
视图形成了 MVC 的 V。不想深入研究 V,因为它与你的问题无关,我假设你已经知道了。
因此,ActiveRecord 提供的模型的“创建”方法与控制器的“创建”操作显着不同。控制器中的创建操作可以调用模型上的创建方法作为其编排的一部分。
保持“控制者瘦”和保持“模型胖”是一种广为接受的做法。确保控制器操作不超过几行(创建操作通常为 5-6 行)。程序逻辑块必须位于模型本身中。
当您调用 user.tags.create 时,不要期望调用控制器“create”操作。只有网络浏览器请求才会发送到控制器。
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
调用继承到Tags
的ActiveRecord#create
方法,这就是TagsController#create
的作用提供了一个我们可以访问的前端。ActiveRecord#create
创建一个新的模型对象然后保存它,与视图或控制器无关,Controller#create
可能会调用模型创建,如果权限正确的话,参数等,但它是作为对来自 Web 端的 POST 的响应基本上模型和控制器是两个独立的实体并通过它们的方法进行交互
阅读有关 MVC 方法的更多信息
user.tags.create
calls theActiveRecord#create
method inherited intoTags
, which is what theTagsController#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 endbasically the model and controller are two separate entities and interact through their methods
read more about the MVC methodology
你是对的。 ModelClass#create 与控制器完全无关。
控制器的工作是响应输入或“操作”,执行任何需要完成的与模型相关的操作,然后设置视图的场景(由控制器方法/操作选择)以显示详细信息。
在较高级别上,模型的工作是封装数据,并且在基于 ActiveRecord 的模型的情况下,协调基于内存的数据结构(“模型”)和底层持久存储(数据库)之间的数据传输。
根据您的编辑,我觉得您想运行 Tags#create 方法,以便完成一些与数据相关的工作。在我看来,这在模型中更合适,因为听起来您正在做严格与数据相关的事情,并且不需要调用控制器方法所涉及的完整“MVC 周期”。您能在 ModelClass 的 before_create 回调中完成您想要做的事情吗?有关 ActiveRecord 回调(包括 before_create)的详细信息,请参阅此处。
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).