I would like to take the community_engine source code and change it so that it can be run as a its own application. The reason I would like to do this is because community_engine contains basically all of the code that my app will use, however much of it needs to be changed or overridden.
I figure that it doesn't make much sense for the app directories sole purpose being either to override a ton of stuff in the engine or to project the engine source that I have modified locally.
I also really want to do this so I will be able to easily see all of the code being used in the app in one place which will make things easier to understand and change.
Heres the community_engine repo: https://github.com/bborn/communityengine
I've asked similar questions as this one in the past but people always seem to think that I just want a to copy the source code to my machine to use locally so hopefully I was better at explaining myself this time:
using devise WITHOUT the gem, can I simply copy the files?
How to convert a large gem to standalone rails app
You could copy the engine in to app_root/engines/community_engine and point the Gemfile to the local path.
gem 'community_engine`, path: 'engines/community_engine'
The engine code can then be editted directly.
Related
I'm building a social network and have been using the gem community_engine but have been having trouble implementing the large amount of customization that I need for my app. I figure this will make it easier for me to override and add methods, as well as help me to better understand and learn from the code since I will be able to actually see all of it in action.
So far in my attempt I downloaded the source code, added the default bin directory and config files that were missing, as well ass all the gem dependencies.
What else do I need to do to get the app to work? I realize that there may still be a lot and that it might not be easy to explain, but at the very least is there any sort of documentation out there that might help me understand how to convert the gem to a Rails application?
Heres the community_engine repo: https://github.com/bborn/communityengine
Because this idea may draw some criticism, I'll add that I was originally building the app without any huge plugins accept for devise however I'm running out of time to finish this.
More stuff I've tried:
Moving files to a new rails app, got server to run but encountered many seemingly random errors, fixed a few but more just seem to pop up that I cant figure out:
I also took a look at http://guides.rubyonrails.org/plugins.html but this gem seems to go beyond that.
I would suggest that you clone the gem and begin copying files from the gem into your a new Rails application.
The engine gem probably has a similar structure to a Rails application, so you should be able to move the files from the corresponding folder to the same folder in your Rails root folder.
You may need to move gem files out of modules, change namespaces etc. Relevant folders to look at files you'll want to include might include app/ config/ db/, any gem dependencies in Gemfile or the gemspec file, as well as spec/ or test/.
Beyond that I think there's no silver bullet answer to your question, you're just going to have to work through problems until you have this up and running, and perhaps ask subsequent questions if you hit on an obstacle that you don't get beyond.
I think what you're looking for is a way to hook your Rails Engine into a rails app. The Hooking Into an Application section of the Getting Started with Rails Engines guide should be exactly what you're looking for.
Here are two additional resources on Rails Engines.
A Guide to Rails Engines in the Wild
Rails::Engine - Ruby on Rails API
How do I create a gem project nested inside my current Rails project?
I've got a Rails project with several parts that could easily be gems. I would like to extract these parts into gems but not leave the current Rails project. Creating new source control repos for the gems add additional complexity that project or organization is not ready or able to handle. These complexities will be overcome at some point and I would like to be ready.
So far I can only think of these items.
Relocate code to a single directory root. I'm guessing this would be in the vendor path
Create a <something>.gemspec
Link to the gem in the Gemfile of the Rails app
gem 'my_lib_code', path: 'vendor/my_lib_code'
What else do I need to do? I'm sure I'm missing something important.
If this were a c project I would create another shared library that the make process spits out. Or if this where a c# project I would make a .dll. For Java I would...
I'm sure Ruby can do the same as all the other languages. Something that is a half way step between a normally fully extracted gem and just some code siting in my lib path.
This is a perfectly fine approach for a component-based architecture.
You have a single repository, a single test suite, and a single deployment process, while at the same time you are "forced" to think of clean interfaces and separation of concerns.
Of course if you are planning on sharing this functionality with other projects, an externally hosted (but not necessarily public) Gem would serve better.
Implementation wise, you can get some nifty ideas from Stephan Hagemann's talk at this year's RailsConf: "Get started with Component-based Rails applications!"
On my server (or laptop for that matter) whenever I install a gem using:
gem install mygemname
or in my gemfile:
gem 'mygemname'
It will install on the computer to some folder on my computer.
Can I go to that folder and edit the file if I want to say add some logging etc.?
If this is not possible, I remember reading that you can have the gem source code installed in your rails 3 application under the 'vendor' folder. How do I install it locally so I can edit it and add logging to it (to learn how it works etc.)
Can you?
Yes
Should you?
Absolutely Not.
Why?
Modifying the gem source makes it very difficult to upgrade to newer versions of the gem
It's much harder to debug an issue
It will cause HUGE headaches down the line
It makes it difficult to work in a collaborative environment (does every developer have the correct hacked gem?)
It causes questions like these (i.e. where should I hack a gem?)
Solutions
There are a few ways to solve this problem:
Submit a Patch
If you feel that this 'change' would benefit the entire community, find the source code (most likely on github), fork, apply the patch, write tests, and submit a pull-request. If the developer agrees that your patch is viable, it will be merged into the project and released with the next version of the gem.
Advantages
You are helping the community
You have a local copy of the gem (since you forked it) on your development machine
Disadvantages
You have to wait for the developer to accept your patch
This can be pretty time-consuming
Re-Gem
If you don't think this is something the entire community would benefit from, but you still want to allow your other developers to use the gem in a systematic way, fork the existing gem, apply your patch, rename the gem, and publish. in this case, it's good practice to prefix your custom gem with the original gem name. For example, if the gem was named foo, you would name your gem foo-my-company. You now can choose to open-source that gem (push to rubygems) or push it to a private development gem server within your organization. You still must source the original gem author in your re-gem!
Advantages
Don't have to wait for a developer
Central code base
Easily shared
Disadvantages
Difficult to update from original gem
Can be cumbersome to maintain
Local Lib (monkey-patch)
You can create a monkey-patch inside your application and override any methods or properties that don't fit your current environment.
Advantages
Quick and Easy
Easily Shared (via git - just include the patch file in your repo)
Disadvantages
Updating the gem is difficult
It's not clear to other developers that you are modifying the Gem's core
Harder to debug (is it an error with the gem or your patch?)
Fork and Source
This is my recommended option. Why did I put it last - the other ones are more common. In this method, you fork the gem from its original repository (probably on github), and then source your gem from your git repo. For example, say the gem was named foo, you would fork foo to username/foo on github. Apply you patches, changes, whatevers. Then in your Gemfile:
gem 'gem_name', :git => 'git://github.com/username/foo'
This will install and compile the gem from source at your repo every time the bundle command is run. You can also specify a particular tag and branch (recommended to stability).
Advantages
You can easily update upstream (you have a fork - pull from the upstream, merge, you have all changes)
Version control is easy (use tags and branches for various versions)
Everyone has access to the same gem source
Easy to manage updates
Disadvantages
Your "custom" code is public (although you could use a custom git server instead of github to solve this)
Conclusion
Each method has its own advantages and disadvantages (which I've tried to enumerate as best as possible). In any event, the method you suggested is not an advised method for solving that problem.
If readers have comments about other advantages/disadvantages, please list them, and I'll add them to my answer.
Sure, it's just code.
Should you? Not in general, since it could be re-installed, updated, etc.
Since you can re-open classes IMO it's safer to monkey-patch, embrace and extend, etc. This isn't always as practical as direct modification, of course.
For educational purposes (when it doesn't matter if modifications are lost), it's fine, and makes more sense than duplicating everything. AOP-ish logging is often doable w/o modifying the original source, though. Sometimes cloning a repo and using it, particularly during exploratory phases, is cleaner.
Dave Newton's advice is wisdom and you should take it, but there's nothing wrong with taking a look at it to learn something. Running gem env will show you where your gems are installed; the lib directory is where you tend to find the meat of the code.
We have had this discussion at work, and it is a practice I discourage.
Gems are made to be updated when improvements and bug-fixes are made. That will instantly wipe out the changes you have done, breaking your code.
You can freeze your version by making it read-only, or use bundler or copying the entire Ruby distribution, but in each of those you are going against the flow.
Instead, I recommend:
Write a patch to the method in question in one of your own files. I've copied the method definition into a separate file in my app's lib directory, and made the change there, then required it last, allowing the method to be fixed without subverting Gem's normal use.
Submit your change to the gem maintainer as a patch, along with your reason for needing the change.
Remove the file and the require if/when the change is accepted.
I used to work at a major corporation that decided it was a good idea to make a patch to one of the source files in their mail system. The software was not something they wrote themselves, so, as time went by, they spent more and more time having to roll in their "special" changes to the software as the vendor grew the product. Eventually, it took months to roll in the changes and made the software fragile, which is not a good thing for something that is a core-business service. Ruby's ability to redefine a method would have saved them untold dollars and months of work.
I have two rails apps that I am thinking about merging into one because they share a similar layout. Right now there is a script in one app that pulls the resources from the other app (including a base controller) into the second app. There are a few ways I have been thinking about doing this:
Merge the apps with namespaces and upon deploy have a script that creates two separate RPM packages (this is for deployment on CentOS/RHEL) with the appropriate files in it
Run one app as the engine of another. Put all the shared controllers and visual assets into the top-level app. Upon deployment rip rip out the engine if I don't need it. (i.e. if it is just the first app and I don't want to give the code of the second app)
Create a GEM with the common controllers and CSS/JS and find a way to inject it into each running app.
Any thoughts/ideas? I am thinking of going with number 1 as it will probably be the easiest for development (2 would be easier for deployment I think)
At Brighter Planet we do (3). Our shared layout gem supports both Rails 2 and Rails 3.
In particular you'll want to look at:
lib/brighter_planet_layout/rails.rb which helps Rails 2
lib/brighter_planet_layout/railtie.rb which helps Rails 3
lib/brighter_planet_layout/rake_tasks.rb which helps you copy shared files into Rails 2 public dirs
How about 4: make three engines (or gems, or engines encapsulated in gems): one for the common stuff, and one for each application's unique stuff?
Have you considered creating an engine with the common controllers, css, and js, then packaging the engine as a gem. When you are working locally, you can have both apps point to a shared development copy of the gem using bundler. To deploy, package the gem with each app, and deploy the whole thing. There are a lot of benefits to doing it as a gem, like the ability to have different versions of the gem in the future so you don't have to update both apps at the same time.
This seems like a pretty decent engines guide: http://www.themodestrubyist.com/2010/03/05/rails-3-plugins---part-2---writing-an-engine/.
I'd be very leery of it, and would probably go with the above approach, but you may consider using symlinks to permanently pull files into one or the other of the projects. I think it's a bad idea, but in some narrow cases it might make sense. It really depends on your exact situation since it's kind of a nasty hack, but nasty hacks can sometimes solve specific problems eloquently.
Most importantly, I'd recommend not merging the apps. The scenarios of modifying the package on deployment to separate the two apps is error prone, and counter to current quality control procedures-- you want the code you develop to match the deployed app as much as possible.
Given that, you want to look at the different modularity approaches. There are actually lots of options for sharing code:
gem
plugin
library code included with a git submodule or equivalent
rails engine
separate deployed app
Probably a shared engine packaged as a gem is the nicest way to go, but it requires you be on the right version of Rails to get the full benefit. Even without an engine, you can get this to work... it'll just take a little more setup.
By "separate deployed app", I mean a third application that has the shared functionality. This may be the needed resources (CSS, JS), and can even be portions of the pages (loaded dynamically). This is potentially a funky solution, but I've seen it work in the right situation.
And any of these solutions requires a bit more effort on the developers' part... but in the end it's better the deployment troubles you'd get by mergine the code bases
I have been working on this, very, small photo cms lately. And now i ready for setting it up to Github. So i will love to have some kind of installer, just as much for leaning it, I'm thinking something like you type a command and then it starts by copy all the files to the rails app, and then asking you for what your flickr_id is etc..
So i have to store all this information and call it down.. i.e if i should show some pictures, i have to use the flickr_id.
Hope you understood my question..
You can start by using rails-app-installer, it's not maintain completly but can works. It's use on the Typo project