Active Admin accessing two models - ruby-on-rails

I would like to access the data from the Profile using Active Admin.
Profile has this model:
class Profile < ActiveRecord::Base
attr_accessible :address, :name, :phone
belongs_to :user
end
Print (orders) has this model:
class Print < ActiveRecord::Base
....
belongs_to :user
has_one :profile
...
end
Both models have user_id column in it, from the User model.
and the Print (Orders) print.rb is written as:
ActiveAdmin.register Print, :as => "Order" do
index do
column "Document", :document_file_name do |print|
link_to print.document_file_name, print.document.url
end
column "Size", :document_file_size do |print|
number_to_human_size(print.document_file_size)
end
column "Print Status", :is_printing
column "Deliver Status", :is_delivered
column "Comments", :comment
default_actions
end
show do
panel "Invoice" do
table_for(order.user.profile) do
column "name" do |profile|
profile.name
end
end
end
end
end
How do i get the data from profile, for example, :address from Active Admin?
EDIT:
I am sharing my solution since someone requested for it:
sidebar "Customer Details", :only => :show do
attributes_table_for customer.profile do
row("Email") { customer.email }
row("Name") { auto_link customer.profile.name }
row("Address") { auto_link customer.profile.address }
row("Phone") { auto_link customer.profile.phone }
end
end

Try this
column :address do |order|
order.user.address
end

Related

Show contents of table but limit to those matching signed-in user

In my quiz game Rails project, I have a table for "Participations" that stores information on the user, the quiz category, and the quiz score after a user completes the test.
class CreateParticipations < ActiveRecord::Migration
def change
create_table :participations do |t|
t.references :user
t.string :category
t.boolean :finished, default: false
t.integer :current_question_index, default: 0
t.integer :score, default: 0
t.timestamps
end
end
end
In my user.rb, I specify an association that a user has_many :participations, which allows a user to play multiple quizzes while storing categories/scores in the table.
If I want to show a user a table of his results (so return all Participations results, but only for those that match the user) in a view, can I call that without generating a new controller?
You can just do like below
#in the controller action
#user_participations = Participation.where(user_id: current_user.id)
and just call #user_participations in the view.
#config/routes.rb
resources :users do
resources :participations, path: "results", only: :index #-> url.com/users/:user_id/results
end
#app/controllers/participations_controller.rb
class ParticipationsController < ApplicationController
def index
#user = User.find params[:user_id]
#participations = #user.participations
end
end
#app/views/participations/index.html.erb
<% #participations.each do |participation| %>
<%= participation.score %>
<% end %>
--
If you have your associations set up correctly, you should be using the associative method (#user.participations), which will basically do what Pavan has suggested:
#app/models/user.rb
class User < ActiveRecord::Base
has_many :participations
end
#app/models/participation.rb
class Participation < ActiveRecord::Base
belongs_to :user
end
Users controller
has_many :participations
def participations
#user = User.find(params[:id])
#participations = #users.participations.build(params[:participation_id])
end
end
ParticipationsController
belongs_to :user
In your routes file you can create the route by
GET 'users/:id/participations', to: 'users#participations', as: 'user_participations'
That will give you a user_participations_path route
So if you wanted to link to it you could add
<%= link_to 'Show user games!', user_participations_path(#participations.user) %>
Then in views/users/participations
<% #participations.each do |participation| %>
<%= participation.inspect %>
<% end %>
Let me know how you go!
EDIT
Please not that the has_many and belongs_to declarations should be in the user.rb and participation.rb models respectively. Thanks to #richpeck for picking up the mistake.

How update field in index list

I have "payment" field displayed as tag, boolean type in my database and if is it possible I'd like to add action on this field. In case when i click on this field i'd like change status from false to true, and reverse. And it all in index list.
ActiveAdmin.register Booking do
permit_params :user_id, :race_id, :payment
actions :all
index do
selectable_column
column :race
column :user
column :payment
column :created_at
column :updated_at
actions
end
end
File routes.rb
//config/routes.rb
scope :admin do
resources :bookings do
member do
get :payment
end
end
end
My file booking.rb
//app/admin/booking.rb
ActiveAdmin.register Booking do
permit_params :user_id, :race_id, :payment
actions :all
controller do
def payment
booking = Booking.find(params[:id])
booking.payment = !booking.payment # toggle the status
booking.save
redirect_to booking_path(booking)
end
end
index do
selectable_column
column :race
column :user
column "Confirm" do |booking|
link_to "Confirm", payment_booking_path(booking)
end
column :created_at
column :updated_at
actions
end
end
What is wrong with my code because i get "uninitialized constant BookingsController". My link: admin/bookings/16/payment
In view
= link_to (#booking.payment ? true : false), payment_booking_path(#booking)
in controller
def payment
booking = Booking.find(params[:id])
booking.payment = !booking.payment # toggle the status
booking.save
redirect_to booking_path(booking)
end
in routes
resources :bookings do
member do
get :payment
end
end

ActiveAdmin association doesn't update its attributes in save

I can't get ActiveAdmin to save the associated model when the initial model is saved.
I have two models that look like this:
# app/models/account.rb
class Account < ActiveRecord::Base
has_one :endpoint, inverse_of :account, class_name: 'Abcd::Endpoint'
accepts_nested_attributes_for :endpoint
delegate :access_key, to: :endpoint
end
# app/models/abcd/endpoint.rb
class Abcd::Endpoint < ActiveRecord::Base
attr_accessible :account_id, :access_key
belongs_to :account
end
My ActiveAdmin file looks like:
# app/admin/account.rb
Activeadmin.register Account do
form do |f|
f.inputs do
f.input :name
end
f.inputs title: 'endpoints', for: [:endpoint. f.object.endpoint || Endpoint.new] do |nested_form|
nested_form.input :access_key,
label: 'Access Key',
as: :string
end
f.actions
end
show do |account|
row 'endpoint has access_key' do
account.access_key
end
end
end
When I click on "Update Account" the Account gets updated but the Endpoint
model doesn't get updated. It appears that the Endpoint attributes aren't
being sent to the Endpoint model.
Does anyone know how to get the Endpoint model to get updated with its
attributes or what I need to fix?
give it a try
form do |f|
f.inputs "Account" do
f.input :name
end
f.inputs do
f.has_one :endpoint, inverse_of :account, class_name: 'Abcd::Endpoint' do |nested_form|
nested_form.input :access_key,
nested_form.label('Access key')
end
end
f.actions
end

creating new association while creating the related record in active admin

I've these two models
class Case < ActiveRecord::Base
belongs_to :client, :class_name => 'User'
end
class User < ActiveRecord::Base
has_one :requested_case, :class_name => 'Case', :foreign_key => :requested_case_id
end
and I want to create adminstration Interface for Case model using Active Admin, so when I create new case I can create new client for it in the same time, so I wrote the following lines of codes in the app/admin/cases.rb file
ActiveAdmin.register Case do
form do |f|
f.inputs "Basic Details"
f.input :title
f.input :Description
end
f.inputs :name => "Client Details", :for => :client do |c|
c.input :name
c.input :mobile
end
f.buttons
end
end
so when I filed the inputs of client and click submit I got this error
ActiveRecord::AssociationTypeMismatch in Admin::CasesController#create
User(#-625154418) expected, got ActiveSupport::HashWithIndifferentAccess(#82665960)
so any help please what's missing here?
Just add to your app/admin/cases.rb file
controller do
def new
#case = Case.new
#case.build_client
end
end
and don't forget to add accepts_nested_attributes_for to your case model
accepts_nested_attributes_for :client

ActiveAdmin how to sort column with associations

I'm developing an ActiveAdmin app, and I want to sort a column of businesses by their "type". Unfortunately my code is not working. What code should I use to accomplish this? Here is my code...
app/models/business.rb
class Business < ActiveRecord::Base
belongs_to :type
attr_accessible :description, :email, :facebook, :foursquare, :google, :manager,
:mobile, :name, :phone, :type_id, :url, :yelp
end
app/models/type.rb
class Type < ActiveRecord::Base
attr_accessible :category
has_many :businesses
def to_s
category
end
end
app/admin/businesses.rb
ActiveAdmin.register Business, { :sort_order => :name_asc } do
scope :joined, :default => true do |businesses|
businesses.includes [:type]
end
index do
column :name
column :type, :sortable => 'businesses.type'
column :manager
column :email
default_actions
end
end
Thanks!
according to this discussion: https://github.com/gregbell/active_admin/pull/623, if you don't want to use scopes, you can use the scoped collection method instead:
ActiveAdmin.register Business, { :sort_order => :name_asc } do
scope :all, :default => true
index do
column :name
column :type, :sortable => 'types.category'
column :manager
column :email
default_actions
end
controller do
def scoped_collection
end_of_association_chain.includes(:type)
end
end
end
FIXED
column :type, :sortable => 'types.category'
Yes, the scoped_collection Evgenia provided works great. Also for more than one columns:
ActiveAdmin.register Foo do
index do
column :field_name_a, :sortable => 'association_a.field_name'
column :field_name_b, :sortable => 'association_b.field_name'
end
end
controller do
def scoped_collection
end_of_association_chain.includes([:association_a, :association_b])
end
end
This can be done.
Here I have a model called Star. A star belongs to a Person. I'm going to put the Person.name in the Star admin index, make it sortable, make it work with scopes, and add filters.
First you have to add the join model to each of your scopes. In this case I had 3 scopes: all, category_subscriptions and person_subscriptions. I'm declaring the scopes and adding the join model to them:
ActiveAdmin.register Star do
[ :all, :category_subscriptions, :person_subscriptions ].each do |sym|
scope(sym, :default => (sym == :all) ) do |stars|
stars.includes [:person]
end
end
end
Now to add the person name from the join model into my star index I do this:
index do
id_column
column("Name", nil, :sortable => :"people.name") {|star| star.person.name}
column("Email", nil, :sortable => :"people.email") {|star| star.person.email}
default_actions
end
Let's dissect that:
column("Name", nil, :sortable => :"people.name") {|star| star.person.name}
The first parameter is the column title.
The second is not needed since we're overriding sort and the value.
:sortable tells Active Admin how to sort the thing. This is the table name, since it's going into SQL.
The block tells Active Admin what to use as a row value.
Now to add some filters. This is much easier:
filter :person_name, :as => :string
filter :person_email, :as => :string
And you're done.
Based on your needs this is my implementation working for sorting, default index and filtering:
ActiveAdmin.register Business do
index do
column :name
column :type, :sortable => 'businesses.type'
column :manager
column :email
default_actions
end
controller do
def scoped_collection
super.includes(:businesses)
end
end
end
Just in case you are wondering how to sort when you have one more level of the association, this is the way I'm dealing with that for eg:
class TechResult < ActiveRecord::Base
belongs_to :user
end
class User < ActiveRecord::Base
belongs_to :organization
end
class Organization < ActiveRecord::Base
has_many :users
end
and then in your tech_results section, you want to render an organization field, in my case the value tech_result.user.organization.name this is the way to sort them out:
ActiveAdmin.register TechResult do
config.batch_actions = false
permit_params :user_id
preserve_default_filters!
index do
column :id
column 'user', sortable: 'users.name' do |tr|
tr.user.name
end
column 'organization', nil, sortable: 'organizations.name' do |tr|
tr.user.organization.name.titleize if tr.user.organization
end
end
controller do
def scoped_collection
super.includes(user: [:organization])
end
end
end

Resources