I am writing a rails application and getting stuck on a routing issue.
My application allows a user to manage multiple cause pages (for various reasons)
right now, I am trying to build the admin screens for users to update their site.
for example, cause pages could look like:
.com/causes/1
.com/causes/2
I and want the admin URL to be:
.com/causes/1/admin/updates
.com/causes/2/admin/updates
etc.
How would I setup my routes to do this
I originally thought something like:
namespace "admin" do
resources :updates
end
But how can I prefix that with the cause/:id so that I can relate which cause I am updating?
You will need to have an admin_controller of sorts and you can setup your routes like so:
resources :admin do
#insert any resource you need to have admin pages on here
resources :causes do
resources :updates do
end
end
end
something like that. Or you could try some rails admin gems to make your life easier like: http://www.activescaffold.com/
Related
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
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.
I'm building a website for a rabbit farmer (let's pretend). This man keeps a close eye on his rabbits, and wants them all categorized. So I built him a RabbitCategoriesController, and added this line to my routes.rb
resources :rabbit_categories
The URLs are showing up as rabbit_categories, rabbit_categoriew/new, etc.
What if I want the URLs to look like rabits/categories rabits/categories/new instead? This is not a nested resource, I just want to change the way the URLs look.
Of course, if the resources were called "categories", I could do
namespace :rabbits do
resources :categories
end
Is there any way I can write that, but tell it to use the RabbitCategoriesController instead of the Rabbits::CategoriesController?
have you tried this, should work
resources :rabbit_categories, :path => "rabbits/categories"
See Rails Routing from Outside In for more details.
I'd like to add a CMS and blog to a web app. One that won't get in the way. There's not a lot of content, but enough that we want non-devs to be able to revise pages and probably add and remove them too.
We have a substantial app that can't be touched by the CMS, not a site that we're migrating.
How have you dealt with this situation?
Would you advise:
Running two apps (a content app and the 'app' app)
Plugging in a light weight CMS
Rolling our own using gems/plugins for WYSIWYG
Details
We'll be adding a bug ticketing and support system later too. Probably built into the app.
We'd like the users of the app to be able to comment on pages and blog posts, file tickets, etc. all from their main account, so it seems to make sense to build it into our app, rather than as an extra app. Love to hear war stories on this.
Should be:
Unobtrusive (Shouldn't interfere with the existing app)
Must not mess with Devise, DeclarativeAuthorization, or Omniauth. We've got extensive user accounts, permissions, authentication mechanisms and groups setup. These must stay.
Lightweight (prefer something dev friendly than feature loaded)
Desired Features:
Basic WYSIWYG for content editors
Lets us handle accounts (with Devise)
and maybe even permissions (with DeclarativeAuthorization)
I've read this similar question, but the author seems willing to have something a bit more intrusive.
Simple Rails 3 CMS Gem/Plugin?
Options Found
Refinery seems to have a lot of features, but at a cursory look it needs a lot of control over what's going on: http://refinerycms.com/guides/attaching-refinery-cms-to-an-existing-rails-application It says it's modular, but it seems like there's a big chunk of non optional stuff in there.
Radiant seems a bit monolithic as well
http://groups.google.com/group/radiantcms/browse_thread/thread/b691cf9ab644a8b2
ComfortableMexicanSofa seems a bit closer to what I want: https://github.com/twg/comfortable-mexican-sofa
Adva-Cms has the right philosophy but appears to be dead. Adva-Cms2 isn't ready
http://adva-cms.org/
Governor seems good, but maybe a bit too young and lean
https://github.com/carpeliam/governor
Conclusion
So far rolling our own, or using ComfortableMexicanSofa seems like the bet, but I'd like your thoughts before I spend a few days messing around with it.
I am now rolling my own blog app and I am kind of newbie to Rails 3. Even like that, in 1 week i have a blog with tags, comments, authentication with omniauth, etc.. my advise is: roll your own. I was having the same doubt and looking for pre-made solutions and I decided to start it from zero and just look for plugins for anything i need.
It goes pretty fast if you know already some rails programming and you use the right plugins. This is what i used:
Omniauth to let users be able to autenticate with facebook, twitter etc.. and leave you comments.
rails_admin: it allows you to manage your blog by going to yourapp.com/admin. It uses devise to create an Admin user (you can specify a diferent model name than user to not to mix it with the users from omniauth or from your other app) and if you have the right models and associations between them you can from there create your posts, assign them tags or categories and also delete comments etc.. its all done in an easy way. For the Text Area that you use to introduce the content of your posts you can associate it with the ckeditor just by adding to the rails_admin initializer something like:
config.model Post do
edit do
field :body, :text do
ckeditor true
end
end
end
And with the ckeditor you can introduce pictures, attach videos, format text, and so on.
Use kaminari for pagination, or you can use will_paginate if you are more used to that.
Using the blueprint framework for styling with css you will save time and have a more standar styling.
Use few jquery lines to insert/delete comments graciously.
And that's all I can remember now. And if it shouldn't interfere with the main app, i would just assign a subdomain for it. So if you go to blog.myapp.com you access to the blog and if you go to myapp.com you access to the app. And you want users from the app to interact with the blog so you should use just one app and have this 2 subdomains pointing at differents parts of the same a app.. take a look at: rails 3 - one app, multiple domains, how implement a different 'root' route for one of the domains?
That's all i can think now! let me know if i can help you in anything else.
rails_admin: it allows you to manage your blog by going to yourapp.com/admin. It uses devise to create an Admin user (you can specify a diferent model name than user to not to mix it with the users from omniauth or from your other app) and if you have the right models and associations between them you can from there create your posts, assign them tags or categories and also delete comments etc.. its all done in an easy way. For the Text Area that you use to introduce the content of your posts you can associate it with the ckeditor just by adding to the rails_admin initializer something like:
config.model Post do
edit do
field :body, :text do
ckeditor true
end
end
end
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