ZF2 - database and models - zend-framework2

I followed this examples http://framework.zend.com/manual/2.2/en/user-guide/database-and-models.html to create a model and a way to save it to a database.
But I don't like the idea of using the AlubumTable-class in my controller as I think this creates too much dependencies. I just want to add the save(), fetchAll(), etc. methods to my model so that I don't have to care about how to save my models inside my controller.
If I want to change the way my models get stored e.g. from a database to a REST-service I would have to rewrite every part of my controller where I get or store models instead of just changing the save() etc. methods in my model.
Are there any tutorials for my way or is this just a stupid idea? :)

The concern you have is actually OK, but you have to realize that the AlbumTable is nothing but a layer between your Controller and the Database. The AlbumTable actually is the one thing with the dependency, not the controller.
The Controller will always need some sort of "Service" or "Gateway" (which would be AlbumTable) to get access to the Data from the DB.
Also i do not understand what you mean by "i want to change the way my models get stored" - You should always store the MODEL into your Service. In the given example the Model is Album and the Service is AlbumTable. No matter where the data comes from - REST, RPC, "normal HTTP", you would always store the Album and not some ArrayData or whatnot. You'd rather try to implement a function inside your model like exchangeArray(), exchangeJson().
You may want to make your "problem" more clear to us...

Related

Should I create model files when only visualizing data in Rails?

I started working on first small rails project which will in fact get data from database and visualize in jquery datatable. There will be no updates at all. The question is, should I create models for this data and access it through activerecord or it is ok to access it directly through SQL commands in controller ?
You should still make models to keep the controller clean.
Rails pattern is that all data access should be done through the models. You don't necessarily have to have any update/insert logic or even inherit from ActiveRecord, but that's where readers of your code would expect to find the data access.
Furthermore, you will need to pass some sort of object to your views, and it makes the most sense to use a model rather than a throw away temp object. This way you can cleanly change the model and only have one place to update.
For example, say you later need to add a full_name attribute to your report. If you had straight SQL in the controller and you were just passing the query results to the view, you'd have a harder time concatinating first_name and last_name. But with a model, you can just add
def full_name
"#{self.first_name} #{self.last_name}"
end
in one place, and all the controller actions that show that report now have a full_name property.
If you plan to do testing, having a model class makes that a heck of a lot easier as well. You can test the model without having to get the controller involved.

Should I make a new Class in Rails for Redis?

I'm starting to use Redis, and first thing my code is not too DRY, and was going to consolidate it in the application.rb and controller. Is this the best way to go, or should I make a new Class called Redis, and have all the logic in there?
My models are currently Customers, Orders, Products, and I'm using a lot of counters.
You will probably need a combination of new and existing model classes.
In many cases you can just drop the model used by the view directly into the datastore, which saves repetition. However, there will always be some places where the needs of the view and the datastore are different.
For example a property that appears as a list of values in the view may need to be stored as a separate set key rather than serialized with the other properties of the model.

Best practice question - Working straight with Linq to sql classes

This is possibly a bit of a stupid question, but I am getting confused due to the ASP.NET MVC book I am currently reading...
Working with Linq-To-SQL it seems to say that it is not good practice to pass the Linq-to-SQL objects straight to the controller, but that each object should be modelled separately first and this should be passed between the controller and the repository.
Say, I have a database of products. Linq-to-SQl creates a product class for me with Name, Price and Whatnotelse properties. I could pass that straight from repository to controller and then view, but instead it seems to recommend that I use and third class, say Product_Entity, with also Name, Price etc. properties and pass that to the controller.
I fail to see the benefit of this approach, except possibly for adding attributes to the properties... But apart from that it seems to have more drawbacks than benefits. Say each product has manufacturer information as well, I don't see how I can model that easily in my third class.
Is this approach really best practice? Or did I misunderstand all that? If so, why is it bad to work straight off the linq-to-sql generated objects? And how do you deal with relationships between objects in y
The huge benefit to this other class you create is that, to use your example, it doesn't necessarily map to either a product or a manufacturer. Think about it like this:
Your Linq to SQL classes are meant for talking in the "data" domain.
Your "data" classes (the ones you're having trouble with) are meant for talking in the "application" domain.
Let's take an example. Suppose in your MVC application you wanted to show a grid of information about products. You want to see their Name, Price (from the Product table) and their Country of Manufacture and Manufacturer name (from the Manufacturer table). What would you name this class? Product_Manufacturer? What if later on you wanted to add properties from yet a third table such as product discounts? Instead of thinking about these objects in purely the data domain, think about them with regard to your application.
So instead of Product_Manufacturer, what about calling it ProductSummaryItem? Each property of the ProductSummaryItem class would map 1:1 with a field shown in your grid on the UI. Your controller would perform the mapping between the information in the data domain (Product, Manufacturer) with the custom class you'd created in the application domain (ProductSummaryItem).
By doing this, you get some awesome benefits:
1) Writing your views becomes really, really simple. All you have to do to display your data is loop through the ProductSummaryItems and wrap them in and tags, and you're done. It also allows for simple aggregation. Say for example you wanted to add a field called ProductsSoldLastYear to your ProductSummaryItem class. You could do that very simply in your views because all it is to them is another property.
2) Since the view is trivial and there's mapping logic in the controller, it becomes much easier to test the controller's output because it's customized to what the view is going to see.
3) Since the ProductSummaryItem class only has the data it needs, your queries can potentially become much faster because they only need to query for the fields that would populate your ProductSummaryItem object, and nothing else. This overhead can become overbearing the more data-domain objects make up your ProductSummaryItem object.
This pattern is called Model View ViewModel (MVVM) and is hugely popular with MVC as well as in frameworks like WPF.
The argument against MVVM is that you have to somewhat reimplement simple classes for CRUD operations. Fair enough, I guess, but you can use a tool like automapper to help out with things like that. I think you'll find fairly quickly, though, that using the MVVM pattern even for CRUD pays dividends, because before you know it, even with simple classes, you'll start wishing you had extra fields which can easily drive your views.

Variable that's accessible to anything in the controller in Rails

I don't know if this is bad form or not, but I needed to set a file path that's accessible to all objects within actions in my controller. One action in the controller creates a file and stores it in a path. Another action serves the file using send_file. The only place I have been storing variables is along with an object in the model. However it seems really silly to store a URL in arbitrarily the first object, or copy the url over all objects. What's the best way to do this?
I hope this was clear.
If this is a file path that is specific to the user of the site, so each user has a different path, you can store it in the session.
session[:file_path] = generate_file!
…user goes to the next page…
send_file session[:file_path]
You could create a method in your application controller that returns the path. This method will then be available throughout your controllers. Don't know if this is necessarily "best practice" but it works for me.
The answer depends on your context. Here is some generic advice:
If there's one file per model, then you need to store one path on each model that has it.
If there's one file shared by several models, but your objects are relatd on a hierarchy, you need to store it on the "father object" - the one that has_many others. The other objects will have to do self.parent.file_path.
Finally, if there's one file used by several non-related models, then I don't know what to suggest, except that maybe there's a better way to organize your models.
What objects are you trying to store, and what relationships are between them?

Where would a method that fetches users from an external source be placed in rails?

I have a Members ActiveRecord model and I want to create a method that would fetch members from an external source and synchronize them with the members in the database already.
I don't know where I should put that method that would be called. It seems like I shouldn't put it in the controller since it is a lot of logic, but I don't know if I can add it to the model since that seems to operate on the row only.
Any advice would be appreciated, I am new with RoR
Based only on the information you've given, I'd make it a class method for the model: def self.get_externals. That way you'd call it like Member.get_externals, and it wouldn't seem to be operating upon a single row like you're worried about.
If in doubt, stick it in lib.
Pulling from the network does not seem like it belongs in the model.

Resources