Custom index views with ActiveAdmin - ruby-on-rails

I'm working on an application with an ActiveAdmin backend and having a hell of a time getting it to render a fairly simple custom index view.
I have a number of 'request' records, which contain an email address and a book_id, by which they need to be grouped. I got as far as:
ActiveAdmin.register Request do
controller do
def index
#requests = Requests.group(:book_id).page
end
end
end
but this resulted in an error: ActiveSupport::OrderedHash can't be coerced into Fixnum
I can create my own custom view in app/admin/requests/index.html.erb but then I lose the standard AA layout with the admin menu et all and can't find a good way to include it.

I ended up doing this using a technique described on their Google Group, in which you just shove the user over to a custom action:
https://groups.google.com/d/msg/activeadmin/YgMzeYBXRno/GZ01Epyq5lcJ
Hacky, yes. I think this is a much needed feature, so hopefully someone can fork and add in support for the index view to take a block with custom content.

Related

Ruby on Rails - Controller without Views

Iam new in Ruby on Rails. Normally I work with other web languages and now (of course) I try to compare it with other languages using on web.
But sometimes i have some problem to understand the philosophy and the character of Ruby on Rails. Of course i understand the concept of MVC.
But now Iam not absolutely sure:
Is ist OK to create and use a controller without views? In some cases you need a "class" for some usefull functionality used by other controllers they have views. Or is it a better style to use a module?
I try to find it out by reading a lot of articles and examples, but didnt find detailed information about this content.
When developing Ruby On Rails apps, it's recommended to put most of your business logic in the models, so for the controllers the logic need to be minimal to provide info for the views, so if it doesn't work with a view chance that you need a controller are really low.
Is it OK to create and use a controller without views
Yep it's okay.
The key thing to keep in mind is that Ruby/Rails is object orientated.
This means that every single you do with your controllers/models etc should have the "object" you're manipulating at its core.
With this in mind, it means you can have a controller without corresponding views, as sometimes, you just need to manipulate an object and return a simple response (for example with Ajax).
--
We often re-use views for different actions (does that count as not having a view):
#app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
def search
render :index, layout: false
end
end
The notion of skinny controller, fat model is sound in principle, you have to account for the times when you may need small pieces of functionality that can only be handled by a controller:
#app/controllers/users_controller.rb
class UsersController < ApplicationController
def update
#user = User.find params[:id]
#user.update
respond_to do |format|
format.js {render nothing: true}
format.html
end
end
end
A very rudimentary example of Rails is a drive-thru:
view = input interface
controller = accepts order & delivers
model = gets order packaged etc in backend
There are times when the controller may not need a view (for example, if you update your order with specific dietry requirements), and thus the notion that every controller action has to have a view is false.
It's really about making your controller versatile enough to manage your objects correctly.
Shared controller methods can be placed in ApplicationController. Also, in Rails 4 there are concerns (app/controllers/concerns/) where you can put the modules with methods that can be used by multiple controllers.
Controller handles request and renders corresponding view template. So controller without view is absolutely nonsense.
Every time request will execute this controller, it will just end with missing template error, so you will need to create view folder and put empty files with action name inside of it, which is obviously stupid.

Multiple index actions in Rails

I have a Game model and GamesController. Currently my index page shows first 10 records from the database for the purpose of the application. However, i want to make another page where all of the games are being shown.
My question is, what's the Rails way™ of achieving this purpose? Is it possible to have the index action of my GamesController to make requests based on what URL i want to render? (Something like http:localhost:3000/all)
Rails 3.1 - How do I organize multiple index actions for the same model?
was the closest to my issue, but the question tackles problem from rails 3.1 dating back to 2012.
You can really only have one index action per controller, but there are a couple of ways you can achieve this.
First, simply create a new action and have a separate page. Think of an appropriate name for it and create the controller, route, and view. You can keep the amount of code to a minimum by having much of the view code in a partial and use that in both views.
The other way to do this, if you really only want one action, is to pass a parameter to the index controller and query the database based on that parameter. For instance:
link_to 'link text', game_index_path(:g => 'all')
will create a url like: http://domain.com/game/index?g='all' and in the controller you can do this:
def index
which_games = params[:g] # should be all in this case
#games = Game.where(:criteria => which_games)
end
You can use this same method to implement sorting and filtering and all sorts of things.

Rails global variable

Im using bootstrap & rails and have a user model and post model..users create posts (collections)..
with bootstrap in the navbar i want the user to be able to click a dropdown which displays the name's of their posts..i did this on one controller with a private method and a before_action but i don't want to do this for all the controllers and it didn't work for the application controller...
is there a better way to do this??
I was doing this
def list
#user = User.find_by_username(params[:id])
#collections = #user.collections
end
and a
before_action :list
at the top of the controller
What's the most semantic way to accomplish this??
If you could move both to your application controller, then it would be available to any controller. More generally, I'm not sure if this is the best approach to solve your problem.
These tips might also be useful.
Are you using devise? Or some other authentication plugin? If so you're likely going to have a current_user helper. This would allow you to simply do #collections = current_user.collections
To the extent possible, I recommend using more descriptive names for your actions and parameters. def fetch_list_collections might be a better name or instead of passing a param named id, perhaps your param should be named username. These naming conventions become extremely important both for others who might look at your code as well as for yourself if you return to it and are trying to remember what you wrote N months ago.
Your list action is generating a N+1 queries. Meaning that you're hitting the database multiple times when you should do so just once. See the rails guide on this. You might also look at ways to avoid this w/ devise. Devise is pretty well documented and I'll bet there is something in the wiki discussing this.
You may want to consider limiting when you call this action - at a minimum - a post request to an update action? What about before they've logged in? current_user might be nil and you'd have an error attempting to call a collections method on nil.
Take your time learning this stuff. You don't have to learn it all at once, but I thought the above might be helpful.
I got it to work with this in the application controller
before_action :list
private
def list
#collections = current_user.collections
end
thanks #arieljuod

How to index filtered records rendering the same view?

I am using Ruby on Rails 3.2.2 and I would choose the right way to proceed when I have to index "filtered" records rendering the same views.
That is, I have articles that are created by an user and those that are not created by that user, and both can be indexed by that user. Since I have to display those records "filtering" articles that are created or not by the user, I thought that a way to handle this situation is the following (in the ArticlesController class and by rendering the same view):
def index
#articles =
case params[:filter]
when nil
Article.all
when "created_by_me"
Article.created_by(#current_user)
end
...
end
Is the above the "right" way to proceed? Or, maybe, I should implement a new controller action like, for example, index_my? Or, maybe, something else?
It is much better to add a filter param to index than build several different index actions. It also allows you the flexibility to add more filters without having to add even more duplicate index actions.

Searching based on field content - Ruby on Rails

So I am creating a ruby on rails application and in my view I have a list of link_to with each being a different console
In my database table I have a field called console.
What I want to do is when a user clicks on a link e.g. Playstation 3, it will return back all records that have Playstation 3 listed in that table column.
I was wondering how I would go about doing this, I have tried searching on the internet but have not found anything similar.
It is for a project that I don't have long to complete. I was owndering what I would state in the link to's in the view and what I would put in the games_controller.
Any help would be much appreciated.
The basic gist is to have a controller action which will return the list of games filtering by console. For example,
# GamesController.rb
def index
#games = Game.find_by_console(params[:console])
end
Then you can create a link for any particular console as such:
link_to 'XBOX', games_path(:console => 'XBOX')
This should result in a GET request to the URL /games?console=XBOX
If you've got a pre-defined set of consoles, you might look into making them into constants inside a Consoles module to avoid having to hardcode them everywhere.
UPDATE:
Since you are trying to implement both searching and filtering in the same chain, you need to make sure that find_by_console isn't called if it's not present.
# GamesController.rb
def index
#games = Game.search(params[:search])
#games = #games.find_by_console(params[:console]) unless params[:console].blank?
end

Resources