Hello guys,
in the official doc of Eloquent for Laravel, this is the way to make an update to a table :
$flight = App\Flight::find(1);
$flight->name = 'New Flight Name';
$flight->save();
I must say, I don't really understand that. For me, it means that for a very basic update, there will be 2 queries to the database - a select and THEN an update ?
Anyone could explain me why this would be a good solution ?
Thanks !
Any abstraction is used for complex applications. The code is too simple that you can not feel it advantage. The Object Relation Mapping (ORM) is used to hide details of operating databases, or running SQL queries.
Just like the MVC model, different layers are in charge of different fields.
View: render HTML
Controller: Logical control, like if .. else ..
Model: data access, like data modification and persistence.
The controller layer won't take care of how model layer works, you just find a object like $flight, and change its property, and save(). That is natural and neat. Your controller layer are all about Object modifying, instead of data modifying.
By separating data and object, you can easily, or at lease possibly, change the implementation of data persistence.
If some objects are frequently changed, you can save it on Redis or Memcached or other NoSQL storage. The controller layer's code needs no change.
If some objects are very large and not modify quite often, you can consider using some distributed storage, or using lazy loading techniques. Your controller code also unchanged. You just change the model layer's implementation, the upper codes will not aware of the change.
Decoupling or layering codes, makes it easy to change any layer's implementation. If you think wring two lines of SQL queries is quicker than ORM, maybe you need to experience larger projects with highly demand changing and performance optimization.
It is always good that separating the implementation and the usage.
Edit:
You can use where and update to update by id. See http://laravel.com/docs/5.1/eloquent#basic-updates
App\Flight::where('active', 1)
->where('destination', 'San Diego')
->update(['delayed' => 1]);
There is some benefit of using this approach if you want to ensure that you're modifying only one valid record.
On the other hand there is another way in the documentation:
App\Flight::where('active', 1)
->where('destination', 'San Diego')
->update(['delayed' => 1]);
It's your preference whether you need to ensure the single record modification or not.
Related
The small web application I am working on is becoming bigger and bigger. I've noticed that when posting forms or just calling other functions I've passed parameters that consist of IDs or a whole instance of a Model class.
In a performance stand point, is it better for me to pass the whole Model object (filled with values) or should I pass the ID, then retrieve from the database?
Thanks!
For Performance benefits, you can do lot of things, common things are
1) Fetch as many as records which are needed, e.g. customized paging, in LINQ use (skip and take methods)
2) Use Data caching in controllers and Cache dependencies for Lists which are bound with View
3) Use Compiled query to fetch records. (see here)
Apply all these and see the mark-able page load speed.
EDIt: For IDs recommendations, In this question, Both will be same performance impact if you pass only ID and fetch rest of the model from database OR pass filled model.
Do not solve problems which do not exist yet. Use a tool to measure the performance problem and then try to solve.
It is always best to consider these from the use case.
For example, if I want to get an item by ID, then I pass the ID, not the whole object with the ID filled out.
I use WCF services to host my BLL and interface to my DAL, so passing data around is a costly exercise, so I do it sparingly.
If I need to update an object, I pass the object, if I just want to perform an action on an object, such as delete or get, I use the ID.
Si
If making things work is only requirement, we can put all controlling login and DB handling logic even in the views & it will work. However this is not a right approach for reusable design.
Before I ask my real design question, below is my current understanding about separation of responsibilities in terms of model.
All Database related code, even db related logic, should go in models.
For a table, say 'my_tab', propel generate 4 classes, out of which only 2 classes 'MyTab.php' and 'MyTabPeer.php' should be edited.
MyTabPeer.php must only have data fetching.
Any logic, if required to fetch data, should go in 'MyTab.php'
This is simple and I hope it is correct, if not, please correct me.
Now, I have a special condition. I've 4 tables, say a, b, c, d. For that, propel generated 8 editable classes (excluding base*.php)
A.php APeer.php B.php BPeer.php
C.php CPeer.php D.php DPeer.php
One page of my application, shows Mailbox (say). Mailbox is not a table in database but it gets its data from complex join query between above 4 tables along with lot of calculation/conditions.
I generated that query, fetch data from it and displayed it. Mailbox is running as expected. However I did it in my controller (action class), which I know is not a right place for that.
My question is, where should I put that code? Possible options:
Controller, I think, is not a right place for DB logic/fetch.
I've 8 model classed however data do not belong to any one of them but as combination of them all.
A separate helper/lib, but I know I'll never reuse that code as its unique page of the site.
Anywhere else?
Please suggest if I'm wrong but I guess I should put it in models as it is fetching data. Since A is primary table, I probably should put code in A.php and APeer.php. If that is correct place, next question is, What should go in A.php & what should go in APeer.php? I've following operations to do:
Some logic to decide what columns, should I select.
As like mailbox, I can show received/sent message. Controller will tell what to show but there are some db logic to set conditions.
Then really fetch data from complex Join query.
Returned data will have all rows but I might need to merge few rows conditionally.
As per my understanding, Point 3 should go in APeer.php and rest in A.php. Is my understanding correct?
You should create separate model class i.e. Mailbox.
Method of this model should do the complex select and return data to your action in controller. This solution will not break MVC approach.
I am wondering how the models in code ignitor are suposed to be used.
Lets say I have a couple of tables in menu items database, and I want to query information for each table in different controllers. Do I make different model classes for each of the tables and layout the functions within them?
Thanks!
Models should contain all the functionality for retrieving and inserting data into your database. A controller will load a model:
$this->load->model('model_name');
The controller then fetches any data needed by the view through the abstract functions defined in your model.
It would be best to create a different model for each table although its is not essential.
You should read up about the MVC design pattern, it is used by codeigniter and many other frameworks because it is efficient and allows code reuse. More info about models can be found in the Codeigniter docs:
http://codeigniter.com/user_guide/general/models.html
CodeIgniter is flexible, and leaves this decision up to you. The user's guide does not say one way or the other how you should organize your code.
That said, to keep your code clean and easy to maintain I would recommend an approach where you try to limit each model to dealing with an individual table, or at least a single database entity. You certainly want to avoid having a single model to handle all of your database tables.
For my taste, CodeIgniter is too flexible here - I'd rather call it vague. A CI "model" has no spec, no interface, it can be things as different as:
An entity domain object, where each instance represents basically a record of a table. Sometimes it's an "anemic" domain object, each property maps directly to a DB column, little behaviour and little or no understanding of objects relationships and "graphs" (say, foreign keys in the DB are just integer ids in PHP). Or it can also be a "rich (or true) domain object", with all the business intelligence, and also knows about relations: say instead of $person->getAccountId() (returns int) we have $person->getAccount(); perhaps also knows how to persist itself (and perhaps also the full graph or related object - perhaps some notion of "dirtiness").
A service object, related to objects persistence and/or general DB querying: be a DataMapper, a DAO, etc. In this case we have typically one single instance (singleton) of the object (little or no state), typically one per DB table or per domain class.
When you read, in CI docs or forums, about , say, the Person model you can never know what kind of patter we are dealing with. Worse: frequently it's a ungly mix of those fundamentally different patterns.
This informality/vagueness is not specific to CI, rather to PHP frameworks, in my experience.
I have a web application built on an MVC design.
I have a database which contains a large number of objects (forum threads) which I can't load into memory at once. I now want to display (part of) this collection with different filters in effect (kinda like what stackoverflow does with questions sorted by date, votes, tags etc).
Where do I implement the filtering logic? It seems to me that this must go into the model part of the application, as only models interact with the database (in my implementation). If I make the filtering a part of the view, then the view must access the database directly to get the list of filtered objects, right? I'd like to avoid this, because it exposes the database layout to the view. But at the same time, displaying different views of the same data should be implemented in the view part of the application, as they are just that -- different views of the same data.
So how do I resolve this? Do I create an additional model, say, FilteredThreadsList, and have it remember the filter to use, and then use a FilteredView to display the list of threads that FilteredThreadsList spits out?
Or do I have to build a ThreadQueryier that allows views to query the database for certain thread objects, so I can have the filtering logic in a view without exposing the database backend?
You should never query data from the view. I don't know what framework you are using in particular but as for Ruby on Rails (should be the same for other frameworks) we always pull the necessary data from the controller and store all that information into a variable. The variable will be accessed by the view which can help you avoid querying your database directly from the view.If the code to query the database gets too lengthy in the controller, insert that code into the model instead so it's more maintainable for your project in the future. Additionally, you can call this model method from multiple places in your application if needed. Good luck!
From an architectural point of view, the model should be having the code for filtering. This is so, because in many applications the code for filtering is not trivial and has a good amount of domain logic in it. (Think of filtering top gainers from a list of stocks). From your example as well, it looks the same since you might want to filter by vote or by date or by tags and then by answered or unanswered etc.
In some very simple applications that deal with search/list of entities and allows Create/Read/Update/Delete of an entity, the pagination, sorting and filtering logic is usually very generic and can be implemented in a controller base class that is inherited by all entity-specific controller classes.
The bottom line is this: if your filtering logic is generic put it in the controller else put it in the model.
Model, that's only bunch of entities.
View provides a visual representation of the data from model - use as much of views as you want. If your application is web based, you can fetch data into browser just once (AJAX) using and re-use them for different UI components rendered in the browser.
As for what entities and what view to use for their representation, I think it's work of Controller. If you need some support for it on "model layer", add it but avoid tight coupling.
I'm probably addressing one of the bigger usability-issues in EF.
I need to perform a calculation on a very big part of a model. For example, say we need a Building, with all of its doors, the categories of those doors. But I'd also need the windows, furniture, roof etc.
And imagine that my logic also depends on more coupled tables behind those categories (subcategories etc.).
We need most of this model at a lot of points in the code, so I'd need to have the whole model filled and linked up by EF.
For doing this, we are simply querying the ObjectContext and using type-safe includes.
But this gets inpractical and error-prone.
Does anyone have suggestions for tackling this kind of problems?
Use projection to get only the values you need, especially if you don't intend to update everything. You probably don't need every property of a piece of furniture, etc. So instead of retrieving the entity itself, project what you want:
from b in Context.Buildings
where b.Id == 123
select new
{
Name = b.Name,
Rooms = from r in b.Rooms
select new
{
XDimension = r.XDimension,
// etc.
Now you no longer have to worry about whether something is loaded; the stuff you need is loaded, and the stuff you don't need is not. The generated SQL will be dramatically simpler, as well.