Re-using model in multiple applications - ruby-on-rails

Due to hosting constraints I am porting an ASP.NET MVC to Ruby On Rails. In my ASP.NET application I had 2 web applications. One for the Admin section, and one for the public section.
Both referenced a class library that held all my Business Logic and Data.
Now I want to accomplish the same thing in Ruby On Rails. How do I use my model in two applications?

First shot: put the business logic and associated models in a plugin.
Second shot: use SVN externals or Git submodules to replicate the exact code in your app, for example under APP_ROOT/lib/ and then require it in your environment.
And last... why not putting the admin and public section in the same app?

I would create a plugin. Call it IceheatSharedLogic or something. Add the model and supporting code to the plugin and commit it to its own source control location. Add that plugin via svn:externals or equivalent to both apps.
But given your use case, is it really necessary to have 2 apps? It seems that would make things complicated if you ever needed any interaction between them (such as putting an edit link on a page, if you are logged in as an admin).

Related

what is the best way to add 4 project with same dashboard and back-end in git?

i have 4 website with different front-end and home-page. but these websites have same functionality and dashboards and same back-end. right now, when i change something in admin panel i should manually change it in all 4 websites. i want to add it to repository in git and when i add some feature in dashboard it update all 4 website. is it possible ? what is your suggestion?
To restructure the 4 website projects so that common parts are encapsulated into a separate (5th) project, which the current 4 would utilize - if that convenience of making just one change.is what you really want - although, you will realize that you still have to repackage all 4 sites (likely adding commits to their repos) each time that 5th, base repo changes.
What you have sounds.fine, actually. Maybe solve the repetitive editing problem by using a diff tool, such as BeyondCompare.

Durandal and ASP.NET MVC conventions

I'm currently evaluating Durandal for use in an enterprise ASP.NET MVC application.
However the default conventions used by Durandal seem to conflict with the MVC conventions I've grown accustomed to.
The HotTowel MVC template by John Papa is great, but this too seems to "do away" with MVC conventions in favour of Durandals by putting things in an App folder.
A couple of the issues I have with these conventions are:
Views are potentially split across two locations (/App/views and /Views).
Scripts are also split across two locations (/App/durandal and /Scripts).
Views are not in the default MVC locations for the RazorViewEngine.
I would prefer to keep each element contained in the appropriate MVC conventions e.g.
/Controllers/
---- HomeController
---- AdminController
/Scripts/
---- durandal/
---- viewmodels/
-------- Home
-------- Admin
/Views/
---- Home
---- Admin
My questions are:
Is it possible to configure Durandal to achieve the above (or something similar)?
Is it wise to venture away from the default Durandal conventions?
What are the potential issues in doing so?
1. Is it possible to configure Durandal to achieve the above (or something similar)?
Yes, you can have any folder structure your heart desires. Durandal does not impose any folder structure on your application but it does have a default convention which is completely overridable.
If you are using Durandals router then you will want to look into how to configure it to find modules. There are many ways of doing this, I prefer to create my own convention by overriding the router.autoConvertRouteToModuleId.
If you are not using the router plugin then you will have to manage the uris for your modules yourself and this is done by following requirejs' convention and using this convention along w/ durandals composition module.
Also, you can override how it finds the views to bind to your modules by overriding the viewlocators convention. Durandal provides an very simplistic way of structuring small applications right out of the box but if you need to build larger applications then it is recommended you create your own conventions.
2. Is it wise to venture away from the default Durandal conventions? 3. What are the potential issues in doing so?
So, there are the conventions of how to discover modules and how to discover views which are completely overridable. And I recommend you do override these and choose a way that suites you best. But, as for placing durandal inside your scripts folder as you have listed above I dont think its a good idea.
The reason I dont recommend this is because I see the scripts folder as a place for all your third party scripts that are NON-AMD modules. This is because Durandal also comes with an optimizer.exe which makes minifying/compressing/uglifying all your html/css/js (amd) files into 1 file.
If you keep your entire application under an app folder and then have the durandal folder inside your app folder the optimizer just works because it lives inside the app/durandal/amd folder. So, when you execute it, it will transverse up 2 directories to your app folder and then scan every subfolder to create a app.build.js requirejs optimization file.. and then it will compress your entire application to one file for you.
This beats having to hand edit an app.build.js file everytime you add a new file to your project. Sure.. there are other tools out there which can do this too.. but you will have to spend time learning their api and how to configure them. If you dont feel like devoting the time to learning something like grunt then this optimizer is kick ass. Personally, I like the ability to just double click something and have my whole application built for me.
As for placing all your third party libraries which are non-amd in a seperate scripts folder I would look into compressing those seperately like using MVC's bundling. The reason I would bundle those seperately is because you know those files arnt changing very often and if you bundle those into a seperate js file they can be cached by the browser seperately. Whereas if your spa is changing, which it it probably will.. then you want the browser to cache that seperately so it only has to re-download your compressed application.
What we do (this is what I have seen Rob doing too:) is that to create folders inside the /App folder depending on the functional areas of the app. Then just create view and view model file inside these folders.
Trick is to have a "viewUrl" property in each view model to tell durandal which view to use.
This way of structuring the application is useful for large projects where there are many views/view models ; avoids confusion when your project grows.
define(['durandal/app', 'durandal/system', 'plugins/router'],
function (app, system, router) {
var vm = {
viewUrl: 'myfolder/myview.html',
};
return vm;
}
);
You can still use viewLocator.useConvention(); when you bootstrap your application; durandal will still find the view as long as you have viewUrl property.

following iterative and agile in asp.net MVC

ok, i know there are a lot of posts online that specify how to do iterations with MVC.
my question is slightly different. when i used to do iterations using WebForms, i was creating one thing only and finishing that one thing till the end which was including the deployment on production.
for example, i was creating a webpage and deploying it, then i create the second page and deploy it. so .dll files were added to my bin folder while the previous dlls remain untouched. at the other hand, when i was making a change latter on, there was this one file that needed to be replaced on production.
now here is the question, how can i acheive the same thing in mvc? beause it just doesn't deploy each page into an individual dll. each time that i add something i have to redeploy the application dll which is not really wise! i played around with deployment options in visual studio but no luck!
There is nothing preventing you from putting controllers and other code in separate assemblies and dropping them in an existing application. Like any ASP.NET based application an MVC application will automatically restart if you add or modify any file in the bin folder or modify web.config.
If you're using Razor you can use RazorGenerator to generate code for your views and compile them into the same assembly.
You may need to write some additional logic though to get routes, model binders etc. wired up correctly.
For a more structures approach to compose the application of separate modules, you may want to look into portable areas. This is an extension to ASP.NET MVC that allows you to package the entire module (including views, css, js etc.) into a single assembly.
First thing, you have to work on the title of the post, it does not match the content of the post.
In asp.net mvc u can choose to deploy only what changed. I.e. If you only changed the .cshtml file, then you can just replace it with the file in production. However if you change any controller class (C#/Vb code), then you will have to upload the web project dll file too so that this new changes are available in the production env

Is it possible to do something like if/else on DBContext to determine which Area in MVC to use?

N00b here. I've been looking around for a bit on how I might accomplish this but have not had much luck, and am hoping for some code examples.
I am using a plugin architecture that is working pretty well. It "discovers" other assemblies (web projects) and then compiles them into the current website's "Areas". Here is the code I am using (for reference) Click Here.
For some of these plugins I am faced with a choice: I have 3 services that would use a plugin, but are unique in some way as to not make the plugin totally reusable. I could just create 3 spearate plugins and pull them into the 3 different main web apps. But then I thought to create an Area within the plugin and got it to work (in that the extra Area is picked up and put into the main website (so Area > Area). I felt the latter approach would work so I created 3 areas within the plugin, with common code being in the main part of the plugin, and each 3 areas having code/views specific to the 3 services.
Now, where I am stumped is in figuring out how I might be able determine which of the 3 services' areas to use when a user is on one of 3 separate websites I have. I can create 3 separate Main apps and pull in the plugins no problem. Each of the 3 websites will have it's own Database, so I started to think that if there was some way to determine which DBContext is being used from the main site then I could determine which of the 3 areas to use within the plugin.
I thought maybe that the main controller of the plugin could have some if/else logic, or some other class file in the root of the plugin could handle that. This is where I need help. Any examples would be much appreciated.
EDIT: Going to try and show the folder structure:
-Plugin1
-...
-Areas
-One
-Controllers, Views, etc.
-Two
-Controllers, Views, etc.
-Three
-Controllers, Views, etc.
-Controllers
-Views
-...
-Website1
-...
-Areas
-Plugin1 <- hidden files in VS2010, created by plugin architecture
-Areas (from Plugin1)
-One
-Two
-Three
-Views (from root of Plugin1)
-Controllers, Views, etc.

How does Grails resolve Controller name conflicts?

What is the recommended approach when an application Controller name conflicts with the name of a plugin's Controller?
I've seen these Grails JIRAs:
GRAILS-4240
GRAILS-1243
...and Burt Beckwith's replies to these two threads imply that the only recourse is to rename one of the Controllers (presumably the application Controller since hacking plugin code is not desirable)
How to use the package name to differentiate between classes in grails?
How to extend/override controller actions of plugins?
However, Burt's own spring-security-ui plugin advocates the exact approach of naming an application Controller the same as a plugin Controller - see spring-security-ui docs.
This approach actually seems to work in both development mode (grails run-app) and when the app is deployed as a WAR. So can this functionality be depended on? If so, what is the Controller conflict resolution rule? The grails docs do not make any mention of it. Perhasps Burt can share his insight?
Having a "plugin" architecture like grails' without even a basic namespacing facility to handle conflicts like this seems pretty broken to me...
The problem is that while you can use packages for any artifact, the convention for controllers is to remove the package and "Controller" to create URLs, e.g. PersonController -> /appname/person/action_name. So in effect everything gets flattened.
In 1.2 and more so in 1.3 things were changed so plugins are compiled separately from application code (and are compiled first) and this gives you the opportunity to replace a plugin artifact with the application's version. Since you shouldn't edit plugin code, this gives you the flexibility to extend or replace a plugin artifact just by using the same name.
I tend to use UrlMappings to get around stuff like this when there are two similarly named controllers. For example say you have an admin UserController that allows low-level CRUD actions and a regular UserController that users work with. I'd name the admin controller AdminUserController and map it to /admin/user/* and leave UserController as is. The admin GSPs will be in views/adminUser and the others will be in views/user so there's no conflict there. This has the added benefit of being able to easily secure - map /admin/** -> ROLE_ADMIN. The conventions are convenient, but this is a simple configuration step that solves this issue for me.
The good news is that GRAILS-1243 will definitely be implemented in 2.0 and possibly in 1.4. And the plugin that Kim Betti references in the comments of GRAILS-1243 looks interesting.

Resources