I have 2 Rails applications mounting a Core Engine. The Engine is used here to group common code between Rails applications (they have very similar business logic but views and some other things differ).
The Core::Engine holds:
common models
common controllers and actions
common libs
common routes
Rails applications holds:
specific models
specific controllers or existing controller actions
specific libs
specific routes
Since I own the Core Engine and the Rails applications, I was wondering about the benefits of using isolate_namespace Core.
Namespacing the Engine will avoid name collision but since my Engine is not meant to be mounted elsewhere, should I care ?
Moreover, namespacing is great but do not play well with routes since I would have to add core or main_app to every url helpers.
Question: Should I care about Engine namespacing in the case where the Engine is designed to DRY up common Rails application codebase ?
Related
I recently stumbled upon ABP (previously Asp.Net BoilerPlate) as a framework to rebuild a web-app in a modular way. It's very interesting indeed, and come with a very wild bunch of basic elements like authentication, logging, security, multi-tenancy, settings and so on...
But, as far as I have understood it by now, ABP is "strongly coupled" with EF Core or Dapper, and I don't like to use ORM in my code, I have a more "database driven" approach and like to write queries myself.
So, the main question is: it's possible to use ABP WITHOUT using EFCore/Dapper? Or it's better to switch to other modular framework like OrchardCore or ExtCore?
EDIT: 11/11/2020 after #hikalkan reply.
Hi #hikalkan, thanks for your kind reply. Maybe I have to explain more what I want to achieve, so you can advise me better. My goal is to create a "pluggable" web-app, in which I can replace a module with another with same functionality but different details.
A little introduction: I have a "complex" web-app for HR departments of small-to-medium companies, many customers use it, and each one have its own copy installed in its premises. The app is composed by many functionality: personal data, contracts data, trainings data, shifts and so on. But each customer have slightly different modules, while the app itself is an old, monolithic one: it works, but I have to maintain different versions, almost one for each customer, very difficult and time consuming. Don't blame it on me, I have "inherited" the app and have to maintain and improve it that way.
But, finally, I can spend some time rebuild it from scratch, and I want it to be "modular", so that the main part (authentication, profiling, db interaction, theming, security, logging, etc...) stay stable & solid, shared among all installations, and each customer have a selection of module/plug-in to choose from. A bit like Wordpress, but better.
For example, let's say I have a simple module "contactSimple" for managing contacts (emails, phone numbers, pagers, and so on), each contact have a type and a value field in the database, very basic, and 90% of my customers are happy with it. But the remaining 10% want to add a note field, a flag "is main contact" or other minor changes. Now, what i want to do is: develop the "contactEnhanced" module as a separetad class library, with same interface and main functions of "contactSimple", compile it as a dll, simply change the dll in the web-app, update the database if needed to, reload the app and the new dll takes place, without altering any other component.
I was thinking to simply use dynamic reflection to obtain it, but then i found that reflection is not very suited, 'cause is slow and heavy on resources, so while surfing the web I find ABP.
Now, THE question: in your opinion, is ABP the framework/solution I was searching for? Please let me know!
ABP is designed to be database provider independent. It currently has two DB provider integration options: EF Core & MongoDB. That means ABP is not strongly coupled with the EF Core or Dapper: It works with MongoDB too. You set -d mongodb if you've created your solution with the ABP CLI.
So, the Framework itself has no relation to any database provider. But the pre-built modules have. For example, ABP provides an Identity module that has user and role management functions and needs to a database and includes some code to interact with the database. So it can't be db provider independent. All the pre-built modules provides EF Core & MongoDB integration packages.
If you want to use these modules (when you create a new application from the startup templates, some modules come pre-installed), you have to decide to use EF Core or MongoDB for the database operations of these modules.
When it comes to you own application code: You are free to use any approach, including ADO.NET with manual SQL queries. Just do it how you do in a regular application. If you want to isolate database queries, create your own repository classes. In this way, you don't see ORM in your code. But the modules still use EF Core or MongoDB.
Actually there a possibility to completely drop the EF Core references: Implement all the repositories needed by the pre-built modules yourself. Then they will work since they only depend on repository interfaces.
BTW; If you use OrchardCore, it uses YesSQL (Yes, YES SQL) as a core dependency and you can not change it because all the OrchardCore framework depends on it everywhere. Also, OrchardCore is UI dependent: It uses aspnet core MVC / Razor Pages UI while the ABP Framework is UI independent and provides 3 built-in options: Angular, MVC and Blazor.
Edit: After edit of the question
The story you've explained is one of the goals of the ABP Framework. ABP is highly modular and also extensible. We built all the modules to be extensible. For example, the module entity extension system allows you to add new properties to existing entities of a module (the module is used as a NuGet package) without touching its source code. You can override the server side logic of the module.
But modularity is hard in general. I mean the module also should be designed so extensible/replaceable. If you want to declare some interfaces for a module, so the module can be completely replaceable, you have a lot of restrictions. For example, you can not write SQL join queries to tables of that module (because the replacement module can use a different table structure).
However, if the customizations will be lighter, you can follow the ABP Framework's module design to make your module extensible/customizable. See https://docs.abp.io/en/abp/latest/Customizing-Application-Modules-Guide and https://docs.abp.io/en/commercial/latest/guides/customizing-modules (commercial docs will be moved to the open source side since they are available as open source now). BTW, ABP supports to load modules as dlls from a folder. It reads dlls and initializes modules on application initialization.
I can only explains what ABP offers. I can't make suggestion, unfortunately. Because a real life project is complex and I can't predict all the problems & requirements you will have in the future :)
This is a question about designing API for frontend components.
For example: If there is any change in Model field in the backend then how can I propagate the same in frontend without changing anything else except model definition with additional field, in loosely coupled backend and frontend
And few more questions come in the same sequence are::
Will the suggested pattern work for the big project?
Is it a scalable solution for API driven micro-services based project?
Will there be conflicts if there are multiple teams working on this kind of project?
Is it good to cache APIs which are mostly frontend component definitions?
As an exercise, I intend to replace all front-facing aspects of my Rails application with Backbone.js. Part of the plan includes redesigning everything right down to the CSS.
The issue I'm struggling with is in delegating responsibility for templates and views.
Is there any benefit to implementing the new front-end entirely in Backbone, hence only using Rails as an API?
How do I strike the right balance between Rails and Backbone when it comes to handling the HTML elements of the application?
Since it seems that nobody is going to post an answer to this I'll offer my two cents as just one point of view (I've written elsewhere about the issue of how to get rails and backbone.js to work well together: rails and backbone working together).
Most people in this situation will tend to drop the rails views altogether and migrate everything to backbone.js.
This is what I've done in a project that I'm working on right now.
This is the natural course of events, and particularly once you start getting used to all the complex interesting things you can do with backbone.js and structured javascript, it becomes difficult to turn back and implement standard stateless HTML pages.
As I mentioned in my other answer linked to above; however, there are costs to completely abandoning HTML views and the stateless layer. In my case, I intend to add back pure HTML pages for non-js-enabled browsers for GET requests only once the app has reached a certain level of functionality. We won't support POST or PUT requests unless the user has javascript enabled (or unless they want to go through the JSON API).
That's the balance I've struck: stateless HTML (no-JS) for accessing data, but JS required for posting/changing data. Your choice will vary depending on your use case and target user.
The other thing that I would mention is that if you have been working with rails HTML views on a project for some time, you might be unprepared for the initial overhead required to switch to backbone.js. This is not simply swapping HAML for ERB: you are migrating from a stateless front-end to a stateful one, and that is a potentially huge change (depending on the complexity of the app). I myself was a bit unprepared for the depth of that change, and had to do a lot of catching up before getting our app back on track after making the switch. And we made the switch very early, with minimal functionality already in-place.
Anyway just a few thoughts, hope they help.
I'm writing an application that manages something like Drupal's nodes. I'm planning on using the app in various content management systems / applications (Concrete5, Wordpress, custom Zend & Yii applications, etc...).
Since I'm using it in so many different places, I have to package an ORM with the app (ie I can't use Conrete5's or Yii's ORM, etc...). I love Doctrine 2, but am concerned that this is too 'big' of an orm to be packaged with my app.
It get's messy, for example, if I'm incorporating this app with a Zend application which is running Doctrine 2. I don't want two 'instances' of Doctrine running in the same app. Is this a warranted concern?
Question: Is Doctrine 2 too 'big' for this project? If so, what would be a good alternative ORM?
If you are going to use your application as an extension for other CMSes and/or frameworks,you should definitley use an ORM for the following reasons which comes to my mind:
1.CMS database installations are different.some use mysql some use oracle ,etc and you will have to create your own adapters or
2.Use CMS's native database abstraction layers.So you will have to rerwite your own model for every cms plugin you are gonna make.
3.Doctrine can do many big jobs but using doctrine is rather easy.doctrine is not resources intensive.
4.using more than one instance of doctrine will not be a problem as far as i know.
5.however doctrine2 requires minimum installation of PHP 5.3 and some shared servers might have older versions of php which this problem will be resolved while time passes and 5.2 becomes obsolete.
However in some CMSes more than one connection will made for your extension to work.(one for the CMS'S native database queries and one for your doctrine query.)
Way 1: work with different ORM's via adapters
(+) better integration with frameworks
(-) a lot of work to implement adapters
(-) loss of flexibility (limited by your adapters interface)
Way 2 (my choice): Use PDO with FETCH_CLASS, it's comfortable enough (you can fetch data to instances of your classes). Most of modern ORM's on PHP works through PDO, so integration must be easy.
Also about Doctrine 2 & Yii -- I tested this combination, works fine.
Why controllers are named "users_controller.rb" and models are not named "user_model.rb"?
Why there is "application_controller.rb" but inside views the folder "layout" is not named "application"?
Code flows from thought best when the naming supports the developers internal model of the problem. When building an application, I don't think of finding a user model (UserModel.find) I think of finding a user (User.find). On the other hand, the controllers are the translation layer between the web interface and the data store (and business logic), so it makes more sense to call them something different.
There's also the problem of namespacing; if both my model and controller are named User, then which User am I referring to at any given moment? In this case, either you name everything with their type, which runs into the problem I describe above, or one 'wins' and is allowed to be referenced 'bare'. It seems to make the most sense that the model would win, so as to provide a better mental mapping.
Inside app/views/layout is application.html.erb and you can have other layouts which are selected by different controllers.
In the end, however, these were choices made during the development of Rails, and they are entirely stylistic choices based on what the developers thought made the most sense, so there isn't really a 'right' answer to your question, unfortunately. In fact, some similar decisions have been revisited. (application_controller.rb used to just be named application.rb.)
Ruby on Rails follows "Convention over configuration" principle. Particularly naming conventions are extensively used by Rails while mapping your routes to controllers, auto-loading and reloading classes, finding appropriate template for an action and many other features.
That principle leads to some restrictions as you can't easily break some of the conventions without getting into troubles. But on the other hand it makes our lives easier as we get smaller amount of configuration and can easily move from one Rails project to the other because all of them have similar structure and follow same conventions. In addition, I believe, that makes Rails core development much easier as core team have a lot of information about how the project using Rails will be structured and they don't have to worry that much about generalization. They simply assume you play by the rules and follow conventions.
Though, I doubt many of naming conventions have serious reasoning behind them. I think at some point someone just decided that it'd be easier for Rails to handle your controllers and distinguish them from other classes if they all have Controller suffix. And here we are having all our controllers in app/controllers directory with that suffix.