List all Items from User by its foreign key - ruby-on-rails

I am using ActiveAdmin and i want to list items which belong to a specific user. The two resources have the has_many and belongs_to relationship.
An index pages is listing all the users. Now i would like to render a show block for each user his items.
My show looks now something like this:
ActiveAdmin.register User do
show do
panel "Specific Item List" do
table_for Item.where("user_id=1").fnidi_each do |i|
column("ID"){|item|item.id}
column("Name"){|item|item.name}
end
end
end
end
How do i inherit the user_id from the page to the show panel ? So that each time show is called i can use the users id for the query.
I know these a basic question but my knowledge of Rails/AA is so far quite basic as well ;) Happy for any advice.

Looking at this code from the ActiveAdmin documentation, where "post" seems to be dynamically generated within the register block suggests that in your case you may be able to just do "user.id", etc.
ActiveAdmin.register Post do
show do
h3 post.title
div do
simple_format post.body
end
end
end
So you might try user.items or Item.where(user_id: user.id) instead of your Item.where("user_id=1").

Related

How to add a panel on index page in ActiveAdmin when index section has no result?

I'm using the ruby gem ActiveAdmin. On the index page, I want to show a few panels in addition to the index listing of records.
I have code like the following:
ActiveAdmin.register City do
belongs_to :country
index do
column :name
column :population
column :elevation
panel 'Languages in Country' do
ul do
country.languages.each do |language|
li language
end
end
end
end
end
The idea is when I go to http://localhost:8000/admin/countries/3/cities, I'll show a list of cities of the country, and below this table, I'll show the country's languages in a separate panel.
The problem I'm having is that when a country has no cities, the language panel is also NOT shown (even though it has languages).
How do I show the language panel when a country has no city data?
Thanks
Subclass and override ActiveAdmin::Views::IndexList, something like:
class IndexListWithCountryPanel < ActiveAdmin::Views::IndexList
def build(index_classes)
if current_filter_search_empty?
panel 'Languages in Country' do ... end
else
index_classes.each do |index_class|
build_index_list(index_class)
end
end
end
Register the customized index page with:
index as: IndexListWithCountryPanel do
... # as before
end
It would be more DRY to always display the panel in IndexListWithCountryPanel and not the index block. Have you considered adding the country languages to the sidebar instead? Disclaimer: this is based on my reading of the code and docs, I have not done this myself.

Rails, REST, which controller displays what?

I have a controller which manages Users and a different one for Reservations.
Where should the code be located that displays all reservations for a specific user?
Is this done in the User controller or the Reservation controller?
It depends. If you're dealing with a nested resource (in other words you want to be able to access something like /users/4321/reservations), you should take a look at this Railscast, which is outdated for Rails 2 but still useful.
What you probably want is to have the code be in the ReservationsController under the index action, but it depends on what you're planning to do. Nonetheless, something like this would make sense:
class ReservationsController < ApplicationController
def index
#reservations = Reservations.where(user: params[:user_id])
end
end
I think you are slightly off base here... your models should have an association; e.g.:
User < ActiveRecord::Base
has_many :reservations
end
Your UserController#show might be
def show
#user = User.find(params["id")
end
And then the view would have something like:
<ul>
<% #user.reservations.each do |r| %>
<li><%= r.details =%></li>
<% end %>
</ul>
The association opens it up so that you can call the needed object from either. You could just as easily show #reservation.user.name in the Reservation view
Where should the code be located that displays all reservations for a specific user?
It depends. If you want to show reservations for a specific user on his detail page (/users/42), then UsersController#show action is perfectly reasonable. If you want to make a search form, then it's basically a filter on the ReservationsControler#index action.

Displaying a column of associated names in ActiveAdmin

I have two models, Listing and Invitation, associated with has_and_belongs_to_many. I am looking at invitations through ActiveAdmin and would like to display the names of the associated listings. I attempt this with the following code:
ActiveAdmin.register Invitation do
index do
column("Listings") { |invitation| invitation.listings.each do |listing|
listing.name
end
}
default_actions
end
end
But nothing shows up. How can I get this to work?
I am assuming that you want a single column with all the listings names of the invitation. Please try the following
column 'listing' do |invitation|
invitation.listings.collect(&:name).join(', ')
end
You might want to customize this later on and add a includes(:listings) to increase db retrieval performance.

how can I get rails_admin to handle associations properly?

Two questions:
1) How can I make a column in the 'list' for a model consist of data from the record's association? In other words, I have a user model and a user has_many posts. I want to simply have a "post count" column in the list. I tried doing:
field :posts do
formatted_value do
value.count
end
end
but that results in a divide by zero error. I even tried doing:
field :posts do
formatted_value do
bindings[:object].posts.count
end
end
but got the same results.
2) How can I filter the listing to a particular scope? For example, I want to make the users post count be a link that is clickable which will show all posts for the given user.
The best I could figure out how to do this was to do:
# note that I created a method post_count to temporarily solve problem #1
field :post_count do
formatted_value do
bindings[:view].link_to value, "/admin/posts?query=#{bindings[:object].id}"
end
end
Which doesn't work very well. Is there a way to instruct rails-admin to do a .where(:user_id => xxx) on the model?
The other thing I wasn't crazy about was having to manually put in 'admin/posts'.. I was trying to see if I could do rails_admin_list_path(:model_name => "posts"). but that didn't seem to work.
You'd probably get a better response on the rails_admin mailing list - http://groups.google.com/group/rails_admin/
For your first question, this should do the trick:
field :posts, :virtual do
formatted_value do
bindings[:object].posts.count
end
end
For your second question, rails_admin now has a filter system - see the "add filter" dropdown at http://demo.railsadmin.org/admin/players . Tapping into that would be a much better method.
rails_admin_list_path(:model_name => "posts") should work, you might have to include Rails.application.routes.url_helpers or similar.
Try adding this to your rails_admin.rb
RailsAdmin.config {|c| c.label_methods << :field_name}
worked for me

Adding a "Like/Unlike" button to a post in Rails

The site is a simple community where each user creates posts and users may "like" them or "unlike" them.
I have a Post and a Like model. Currently, I'm listing all posts and also the likes size for each post through post.likes.size . The button to like a post is also working.
What i don't know how to do is how to depending on the case, if a post should show the unlike button or the like (depending if the current_user already liked that post).
The like model is very simple:
User_id // current user
Post_id // post to associate
Thanks in advance!
You should define association in user model
if it's ror 2.* add method in User model. it should look like this:
has_many :likes
def already_likes?(post)
self.likes.find(:all, :conditions => ['post_id = ?', post.id]).size > 0
end
Assuming Like has fields user_id and post_id
and of course in view
if current_user.already_likes?(#post)
#add unlike button
end
You want to search for a record that matches the user_id and post_id. If you find one, you want to show the 'unlike' button, b/c that means the user has 'liked' the post already. If you don't (it returns nil), you want to show the 'like' button.
The following method returns nil if the user hasn't 'liked' the post, and not nil if the user has 'liked' the post.
def user_likes(current_user, post_id)
likes.find(:first, :conditions => ['user_id = ? AND post_id = ?', current_user, post_id] ).nil?
end
So you can say:
if user_likes(1, 12).nil?
# show like button
else
#show unlike button
end
Also you could add validation to your Like model like so:
validate :user_does_not_already_like_post
def user_does_not_already_like_post
errors.add(:user, "You can only like a post once.") if user.already_likes?(post)
end
create an action like this in your posts controller.
def unlike
# get the post
#code to decrement the like counter of a specific post
end
then from your view, create a button or a link that points to this action.

Resources