Rails 3 controller from plugin - ruby-on-rails-3

I am creating a Rails 3 plugin and I want to integrate controllers in it that will be automaticly consider by rails as a "normal" controller from the app/controllers folder. How can I do that or what is the best solution for me to have custom controllers from a plugin?
I have found documentations from guides.rubyonrails.org but they have changed the documentation and plugin development doesn't include controllers anymore.
Thanks

You will need to define a class within your plugin that inherits from Rails::Engine. In effect, the feature you want is an engine.
Define the class like this:
lib/your_thing/engine.rb
module YourThing
class Engine < Rails::Engine
end
end
You can then define your engine's controllers at app/controllers within that plugin and for them to work neatly you will also need to define routes for them, which you can do inside config/routes.rb inside the engine like this:
YourThing::Engine.routes.draw do
resources :things
end
Next, you'll need to mount your engine inside your application:
mount YourThing::Engine, :at => "/"
The application then will be able to use routes from your engine.
For more information, I'm in the progress of writing the official Rails Engine guide which you can reference here. Please let me know if you have any further questions and I'll try to answer them in the guide.

Related

Where to place "common" classes in YII Framework structure?

I need to create a few classes and would like some help on where this would go in the YII Framework. I know if I create a Model, it must go in the "models" directory. And by the same logic I know where "views", "controllers" etc would go. However, where would the following be placed in my web application:
A class that contains a variety of "number" functions such as currency conversion, metric conversions etc?
A class that interacts with a REST API? (It interacts with the database)
Any tips?
To get started with adding custom classeses on YII you can check below link.
http://www.yiiframework.com/wiki/165/understanding-autoloading-helper-classes-and-helper-functions/
Hope it'll help you to start.
You can find an example here, it is pretty detailed in my opinion:
The directory structure of the Yii project site
Usually you can use any PHP class in within Yii. You can place it in the models folder (alongside the Yii generated models) and access them directly like so:
$myclass = new MyClass;
$myclass->methodname;
Alternatively (or if you run into any issues), you have can place it anywhere in your directory structure and include it in the main index.php (in the root) like so:
$myclass = dirname(__FILE__).'/myclass.php';
require_once($myclass);

How to create user specific content, that is invisible to others?

I am absolutely new to Ruby on Rails, even to programming at all. I got started with Michael Hartl's Rails Tutorial using Rails 3.0.10. Now I alter its aim towards creating an application that allows users to manage their own "projects". These projects are to be exclusively available to the logged-in user, thus, invisible to others.
My problem is: I am unable to create a page with an URL like "~/users/1/projects", I don't know about the routing. All i get done is "~/projects", which is fairly not what i want at all. So, how do I get this problem fixed? Or am I totally off track with that idea?
I generated a Projects model by scaffolding. So, how can I implement it for the signed-in users?
this would be done by creating a nested resource. when you are new to rails and programming you should work yourself a way through a lot of tutorials and guides.
a good place to get an overview are the official rails guides. in this specific case the chapter about routing: http://guides.rubyonrails.org/routing.html#nested-resources
# config/routes.rb
resources :users do
resources :projects
end

rails 3.1.1 engines - with mountable engines, is it possible to access parent app assets, default layout?

This is more for experimentation - I am aware that I can do this with --full but I wanted the functionality of namespacing in the app to avoid conflicts
The idea is to have a main app - which handles authentication, common items, admin screens etc
Then creating engines to add further functionality like
crm
cms
blog
wiki
forum
etc
These engines I can pick and choose as I need for whatever kind of app I am building.
Is this possible?
Is it just the case of applying both --mountable and --full options?
Experimenting - would there be any issue if I use the full option add rspec and then simple add
rails plugin new plugin_name --skip-test-unit --full --dummy-path=spec/dummy
and in lib\plugin_name\engine.rb
module PluginName
class Engine < Rails::Engine
# this is added by rails when an engine is mountable
# to isolate the plugin and prevent name clashes
isolate_namespace PluginName
# one of the additions to make rspec work from command line for the plugin
config.generators do |g|
g.test_framework :rspec, :view_specs => false
end
end
end
I have already created both --full and --mountable engines and have rspec finally working for anyone reading there are some great articles (see below), but wondered of the wider impact of doing this for the solution I am trying to create
I am still playing with this and will post my findings..
Any help/discussion will be massively appreciated.
Please Note
Why I want to do it - build once use many times...
I would never want a non-tech/client to add "plugins/engines" - this is purely to entertain point 1.
Issues I am Having...
Running the server on the top level app. Only when accessing content from the engine, (I can see by the error messages) I have a routing problem (root_path undefined or devise routes missing) - the parent application layout is being rendered, I can see it in the extracted source of the error. Progress but no cigar just yet!
Useful References
Engines vs Mountable Apps
3.1 engines with rspec
testing rails 3 engines
Listing Routes in a Mountable engine
I managed to get this working with the following steps:
In my parent app I was mounting the engine in routes.rb
mount PluginName::Engine => '/plugin_name'
I just removed it.
Created an application controller as Ryan Bigg below had stated.
class PluginName::ApplicationController < ApplicationController
...
end
As I wanted to have things name spaced when generating controllers, models, tests so you have to essentially comment out the isolate_namespace PluginName lib\plugin_name\engine.rb when I wanted the gem to be run in the parent app.
It is not yet an ideal solution. off the top off my head, I could use something like:
isolate_namespace PluginName if %w[development testing].include?(Rails.env)
but will have to test if this is practical.
Kudos to Ryan for helping me find my way many thanks
Furthermore, the same can be done with the --mountable switch version and all you need to do is one further step in your engines config/routes.rb replace
PluginName::Engine.routes.draw do
with
Rails.application.routes.draw do
Yes, you can reference the parent application assets just by referencing them in your application like normal:
<%= stylesheet_link_tag "application %>
Although, not sure why you would want to do that because...
I'm going to answer your first question with the answer to your second question.
To use the application's layout you will need to modify the ApplicationController in the engine (which is namespaced) and have it inherit from ApplicationController in the engine.
That will then have the controllers for the engine using the layout provided by the engine. I'm doing this in my engine, forem.
One day, this will be covered in the Engines Guide that, at this time of writing, is currently being written.

Can I use/adapt the Kohana userguide module to create help pages for my application?

I'd like to create a userguide for the application I'm building using the Kohana framework, and I'm wondering if there's a way I can use the Kohana userguide module for this purpose.
I understand how to add userguide info for new modules that I create, and how to include my classes in the API, but I want to build a second, separate userguide for the actual application user, as opposed to the app developers.
At first, I thought I'd just try adding app help pages to the main userguide at APPPATH/guide. I tried adding a "application/guide" directory, and put a file in there called menu.md, but that just ended up replacing the Kohana menu in the userguide. After renaming the file to menu.myapp.md, it doesn't show up at all.
So then it occurs to me that I could simple edit modules/userguide/guide/menu.md to add sections for my app, and likewise add markdown files for each app component. But really it would be much better to have a completely separate userguide for app users since the Kohana documentation isn't relevant for them.
What's the best way to go about this? Should I create a duplicate of the entire userguide module and modify the routing, &c.? Or is there some way to set up both userguides using the one version of the module? Or am I barking up the wrong tree altogether? Is there some other module/approach that would be better for building "Help" pages for the app?
Thanks in advance for your help!
Yes, you can make docs for your application with the userguide. If you want examples, check out these links:
https://github.com/zombor/Auto-Modeler/blob/master/config/userguide.php
https://github.com/zombor/Auto-Modeler/tree/master/guide/auto-modeler
Note that you'll still get "api docs" and everything else, unless you change the config to hide them.

How to connect Social Media Streams (Twitter, Instagram) in Rails

I am doing my first baby steps with Rails (version 3) now. I'd like to create a simple app catching data from the twitter/instagram/ API. Thankfully there are already gems doing the heavy lifting with connecting to the services, providing the data. Now I wonder what the best-practice is to add this functionality to Rails correctly.
My feeling is the best way is to create a new non-DB Model for each service I want to include and create some scopes, which I will then use in the controller. The scope definition includes the functional code, instantiating and using the twitter/instagram gems to get the web service's data.
Is this model/scope approach right or did I miss something?
In future I might need to cache all the fetched data to handle common API request limitations. Is there any good approach for this?
I'd appreciate your thoughts or examples/resources on this topic.
I think in this situation a standard class would be ok e.g.
class TwitterImport
def get_tweets
# Download tweets
...
# Create tweets
Tweet.create(.....
end
end
I created something similar recently. I created a folder called scripts in my app directory and stuck a class in there called import.rb. Because this file lives within the app directory it automatically has access to the Rails goodness i.e. existing Models etc.
I then set it up as a rails runner script, you run it via teh console from your app's root directory:
rails runner -e development TwitterImport.get_tweets