ActiveAdmin: Make index pages link to edit action - ruby-on-rails

ActiveAdmins DSL for index pages provides a simple means to link to associations, like e.g.
ActiveAdmin.register Rental do
index do
column :user
end
The users name in the created column will automatically be linked to the show action of the associated user.
Now if in User we disabled the show action like so:
ActiveAdmin.register User do
actions :all, :except => [:show]
AA will still generate links to the show action instead of to the edit action, as one would expect.
Is there an easy way to specify, that AA should always automatically link to the associations edit action?
Update:
I found out, that the link is created in ActiveAdmin::ViewHelpers::AutoLinkHelper.auto_url_for(resource) but I don't see how that could be made configurable.

This bug just got fixed in activeadmin master in this commit:
https://github.com/activeadmin/activeadmin/pull/3754
ActiveAdmin will now link to the edit action if the show action was disabled.

Related

How to add the current id to another table in ruby-on-rails?

I am new to ruby-on-rails and have a probably pretty stupid question:
I have a ruby-on-rails-model for a book-list. On the "show"-page I have a button which should take the current id and create a new entry in another table where this id is saved as an integer.
Example:
I am on the page /titles/4 and want a new entry with the value 4 in the title_id field to be created in the table list.
How is this possible?
You should create a new controller with the create action and the associated routing.
Then you can use your route in button and pass current_id to the new controller in params.
I will use books as this second table name for this example.
First, you need to set up routes for books resource:
resources :books, only: :create
Unless you plan to add other action in BooksController its good practice to list in your routes.rb only the one you are using.
Next, you need a BooksController with create action, similar to the one you created for titles it might look somewhat like this:
class BooksController < ApplicationController
def create
# code to create a new book using provided params
end
end
Last but not least you need a button from /titles/4 site which will lead to your new BooksController via proper route:
<%= button_to "Add book", books_path(title_id: #title.id, method: :post) %>
Breaking it down:
Add book is just the name of a button displayed to the user
books_path is a path generated automatically by rails from your routes.rb file. You can look up your current routes by typing rails routes in the terminal while in the project directory.
title_id is a key under which it will be passed to our BooksController you can pick it up there to create a new book
#title.id I suppose that in current view you have access to such instance variable and can pick up its id value thanks to this call - if not pass it in show action of TitlesController
method: :post leads our routing to create action of BooksController
Hope this solves your problem!
The best solution for you will probably be to use Nested Resources. If your "other table" is reviews, it would be something like:
resources :titles do
resources :reviews
end
Your route would be:
/titles/4/reviews/new
And you could access the Title ID from the route by using params[:title_id].

How to add a button in ActiveAdmin to create a new record for another resource, with fields pre-populated with values from the current resource?

In my ActiveAdmin dashboard, I have two resources - Posts and ScrapedPosts. For a ScrapedPost, I want to add a Publish Post button, which, when clicked, goes to a page for creating a new Post (new action), where all the fields for Post are pre-filled with values from ScrapedPost (Post and ScrapedPost have identical schema).
Here is my current code inside app/admin/scraped_post.rb
ActiveAdmin.register ScrapedPost do
action_item :view, only: :show do
link_to "Publish Post", new_admin_post_path
end
end
This adds a new button called Publish Post. When I click on it, as expected, it creates a page for adding a new Post. However, I want the fields pre-filled with the values from the current ScrapedPost from where I am creating the post.
I have tried a number of things so far. The documentation for action_item is very basic and it didn't help. It looks like I can't pass parameters to the action identified by new_admin_post_path. How can I do it?
[I started learning RoR just this week, so I'll be grateful if you can explain your solution as well.]
All action_item is doing is injecting a link styled as a button onto the show page. You can pass parameters to the link target by embedding them in the link. However, new does not accept parameters so to copy a Post what you need is a member_action:
member_action :clone do
resource.clone
render :new
end
This action can be invoked so:
action_item :clone, only: :show do
link_to "Publish Post", clone_admin_post_path
end
Make sure first that works for copying a Post. If you want to create a ScrapedPost from a Post then you will need to pass the id of the Post as a parameter:
link_to "Publish Post", clone_admin_scraped_post_path(post_id: resource.id)
then the ScrapedPost member action can find it:
member_action :clone do
#scraped_post = Post.find(params[:post_id]).clone.becomes(ScrapedPost)
render :new
end
As an aside, for better or worse ActiveAdmin is an additional layer of abstraction on top of Ruby on Rails so my recommendation is always to master vanilla Rails first to ease the learning curve.

creating multiple web page in rails 3 project

I am fairly new to Ruby and Rails. I am using rails 3. I am creating a project where people can login and post jobs and people can search jobs etc. I have created my users model and jobs model and everything is working just fine. I have started creating the home page layout and have added links to the other pages post work, find work, contact, about. I have a few questions hopefully someone can help please.
When I get into the rails server and check out the project and my home page it shows the login set up from the users model and it also shows the jobs model where someone can post a job. I am trying to figure out how I can make it so the jobs do not get posted on the home page but the find work page and people can search from that page? Do I need to link the jobs model to the find work page something like that?
How do I create the web pages for these other links i have established. I can not figure out how to build the page layout for the post work link i have or the other links I have for people to view the page layout. Any help is appreciated? Thanks again!
What you ask is mostly the basics of Rails. You can render jobs or any other model in any view you want, you just need to "send" these jobs to the views from you controller.
1.- Configure routes:
#config/routes.rb
get "/jobs" match 'jobs#index' # i.e 'controller#action'
2.- Configure model controller:
#app/controllers/jobs_controller.rb
class JobsController < ApplicationController
def index
#jobs = Jobs.last(10)
render 'index'
end
end
3.- Configure view:
#app/views/jobs/index.html.erb
<% #jobs.each do |job| "do something with each #{job}" end %>
This is just a birds sight overview you should check some Rails tutorials.
About generating pages for content that isn't in the db...
I had this issue once and solved it like this:
#config/routes.rb
get "/:view" match 'home#views' # rails g controller home
#app/controllers/views_controller.rb
class HomeController < ApplicationController
def views
render params[:view]
end
end
Now generate a view for each new page, lets say "About", under /app/views/home and you can access each of them via /view_name.

Would it be better to create an entirely new action in my controller or should I create a new controller in Ruby on Rails?

Basically I have an existing CollegeClass Controller that has the default basic RESTful actions like show for showing the webpage for that college class,edit for editing, and update for the post action of editing the page itself. I need to add an additional single "About the class" webpage to this resource which will not add another model. It will just add another field to the existing CollegeClass table for the html that will present the new page.
Should I create a controlller exclusive to the "About the class"? Or should I add on into the CollegeClass controller new actions? Or do I need to nest this?
Thanks for your help
I would go with the custom action and just route it inside college routes as
resources :colleges do
member do
get 'about'
end
end
CollegeController < ApplicationController
def about
end
end

View show page for menu item in Active Admin

I would like to dynamically change the menu based on the permissions of the viewing user. I would like the superadmin user to have access to the normal Resource actions (index, show, update, etc). So when an admin clicks on a menu item, it would take them to the index of that resource. I would like to restrict the normal admin user to just viewing a specific show page.
The menu route for the superadmin would be: /admin/resource
The menu route for the normal admin would be: /admin/resource/id
I would also like to restrict normal admin access to the index view, or other resources that they don't have access to. I have been able to achieve both these things, but I have yet to be able to map a menu item to a specific show page. I know I could create a custom page and view, but I really would like to share the custom DSL for the show and edit pages between superadmin and the normal admin.
Anyone know how to make this happen.
Ok, so I figured a way to get what I want. I am not sure if exactly fulfills what I wanted. (meaning, it would be nice to create custom menu items that are mapped to specific resources)
I just overwrote the index controller action to redirect to the specific show page. Because the super admin needs access to the original Store resource, I had to alias it with :as.
ActiveAdmin.register Store, :as => 'My Store' do
menu :if => proc{ !current_user.is_admin? },
:label => 'My Store'
actions :show, :edit, :update
controller do
def index
redirect_to(admin_my_store_url(current_user.store))
end
end
end

Resources