How to map id to name in active admin index? - ruby-on-rails

I am using active admin. I have project and user model with many to many relationship between them. In my user model i have a project_leader boolean column. And in my project model i have project_leader as integer column. I am allowed to select 1 project leader for each project. And then id of the user who is the project leader is stored in Project project_leader column. How do i map the id of the user to its name from active admin index?

Solved:
In my project model i defined a method as following.
def get_associated_user
p = self.project_leader
user = User.find(p).full_name
end
And from the active_admin index i just called the method object.get_associated_user

You can do it lik this too
column "Project Leader" do |p|
user = User.find(p.project_leader).full_name
end

Related

User role change with project

I need following association in my app.
User has many role,
Project has many user,
user1: manager for project 1 & employee for project 2
I am not getting idea about how can I set relationship between these tables and models.
User, Role and Project
How can I set this up?
Thanks a lot in advice.
All you need to do is use some gems.
Devise
Rolify
Then create the project model + controller + views.
create a new user - User.create(email: "user1#example.com", password: "123123")
add role to the newly created user - User.last.add_role(:manager)
create another user - User.create(email: "user2#example.com", password: "123123")
add role to the newly created user - User.last.add_role(:employee)
Now, if you do all the steps right, then create a new Project:
user1_project = User.find(1).projects.new(project_params)
It will create a project for user with email user1#eaxmple.com who has manager role.
Well you can do something like this,
Create a table call role and give unique id to each role_type, like
1 for manager, 2 for employee, 3 for owner etc.
And create another table which have the following fields,
user_id,role_id,project_id
So if user1 is manager of project1 then we will have a entry with the following entry
user_id = 1, role_id = 1, project_id = 1
and user1 is employee for project2 will have an entry,
user_id = 1, role_id = 2, project_id = 2
here role_id 1 and 2 corresponds to manager and employee respectively.
You could achieve this setting up Rolify gem.
class User < ActiveRecord::Base
rolify
end
class Project < ActiveRecord::Base
resourcify
end
Now you can add multiple roles to user object either by specifying particular project object or Project class or without these. For example:
user = User.create(user_params)
project_1 = Project.create(project_params)
project_1 = Project.create(project_params)
# Add roles with respect to specific project object
user.add_role('manager', project_1)
user.add_role('employee', project_2)
Please go through this rolify documentation to get the detailed overview and usage examples.
if you asking about how to add the relationship to the tables.
Here is an example
Let's say
Users -> user1, user2
Roles -> Role1, Role2
Projects -> P1, P2
Users -> Roles ( foreign key relationship ) users depends on Roles
Roles -> Projects ( foreign key relationship ) Roles depends on Projects
Here let's treat project as resource where a role can access them
Users -> Roles -> Projects
Roles can have read permission on P1 and read-write permission on P2 etc

How do I make a field referenced to appear in the active admin view on rails

I have two models, one users and one account managers, The users table has an account managers reference field.
However, when I select the users, all there information is listed except the user's account manager.
How do I make the account manager appear when I click the Users link in active admin.
In your app/admin you add
permit_params :account_manager
and in the index you add :
index do
column :account_manager do |a|
a.account_manager_for_user
end
where account_manager_for_user is a method that returns the account manager in the user model:
def account_manager_for_user
self.account_manager
end

Complex sorting in Rails

In my application there is a Membership model with attribute username_or_email, which is used to invite users to system. When user accepts invitation, the Membership object is updated with a relation to new User object, who has a name attribute. Now I would like to sort every Membership objects in a single view, and show it like this:
If there is already user registered, show name attribute from joined User object.
If there is only invited user, show username_or_email attribute.
How can I easily sort it alphabetically by two columns?
Here is how you might do this (let's assume using PostgreSQL)
A scope on Membership that handles the query
# class Membership
def self.ordered_by_formatted_name
joins("LEFT JOIN users ON users.id = memberships.user_id").
order("COALESCE(users.name, memberships.username_or_email)")
end
An instance method on Membership for the display logic
# class Membership
def formatted_name
user ? user.name : username_or_email
end
Example usage
#memberships = Membership.ordered_by_formatted_name.preload(:user)
<% #memberships.each do |m| %>
<%= m.formatted_name %>
<% end %>

What query do I perform to access the last of a collection of models before they have been saved?

I have a Workflow model, an Action model, and a Role model. Actions are nested attributes of a workflow, and an action has and belongs to many roles.
The associations work fine. However, in my form view, I need to add a role to the last action that has been build (note but not created).
The Workflow controller:
def create
#workflow = Workflow.new(workflow_params)
if params[:add_role] # from a submit button
Action.last.roles << Role.find(params[:role_id])
# doesn't work as no actions have been created
...
elsif params[:add_notify_action]
#workflow.actions.build # cannot save because parent hasn't been saved
end
In short, how do I get to the last Action that has been built in my controller? By definition, it's not in the database.
In long, if I can't, what's another option to get the roles added to the actions?
If an Action is a nested attribute of Workflow, when you initialize a new workflow passing the params, you initialize a new Action association. Then you could just go ahead and do:
#workflow.actions
to access the Actions. You cannot get the last one unless the Action has some attribute that defines that "last" characteristic (like a date given by the user). So consider saving them and then getting you can the last one by ordering them (created_at and updated_at fields). And before adding the persisted Roles, you'll need to also persist the action.
In the end, I decided to create a #current_action_id in my controller that I would update each time I called #workflow.actions.build. I ended up with this add_role method.
def add_role
unless #workflow.actions.empty?
#workflow.save!
role = Role.find(params[:role_id])
roles = Action.find(current_action_id).roles
roles << role unless roles.include? role or current_action_id <= 0
end
end
Thank you #engineersmnky for the tip on saving my workflow before adding the role.

Display values in model B that belongs to A

I have a Company.rb model that has_many :applications what I am trying to now is to show all applications the company has created.
When a Company creates an application I store their id inside Application.rb in the column called company_id by using merge on #create.
What I am trying now is to make it so that I can have a page where they can see the applications they have created. How do I only show applications that match current_company.id with the company_id in the Application.rb ?
Try this;
#applications = current_company.applications
Then use #applications in your views.

Resources