Rails: spliting table between two forms - ruby-on-rails

The Rails application I'm working on, has two central pieces: users and groups. A user registers through a form, and is added to the users table.
The groups table has four primary columns: name, title, description, and membership.
Groups are handled in two steps.
Step1: the admin creates the group (name, title, description).
Step2: Membership is a JSON field. Admin needs to log in using a second form, and add/edit that JSON structure's fields: group owner, group admins, members, parse / re-parse into a JSON and update the groups table.
The user signup, and groups creation form are working fine. The problem is the second form: creating the group's membership. I am not really sure how to proceed.
What I did is create the link and routes to properly select from the groups, and produce a REST call with the correct params by adding additional routes and links on the Show page. I verified that the l ink is correct, when I hover over it, I see http://myapp.com/groups/3/admin (3 is the correct ID in the groups table).
The methods in my groups_controller.rb are similar to the following:
def show
#group = Group.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #group }
end
end
I created a groups_admin.html.erb and put it in the views/groups folder. It has in it the logic to construct a set of drop down boxes, allowing the admin to pick from the users list to fill the group membership (the functions are in the groups helper).
What I don't know is how to complete it with a form declaration, etc. in groups_admin.html.erb and what to add to the groups_controller.rb to cause an UPDATE to that particular row (after I turn the returned fields into a JSON). So far, here's what I have added to it
def admins
end
Changing the groups table schema and creating additional groups_admins, groups_owners, groups_members tables is not an option. Any ideas?

You're looking for associations. In this case you probably want a group has_many users and a user has_many groups. Or if you want a user to be able to be in multiple groups you're looking for a has_and_belongs_to_many association. You can read up on this here: http://guides.rubyonrails.org/association_basics.html

Related

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

Search two models with Ransack Parameters

I have two models: Patient and Facility.
Creating a new patient I have a modal that opens and does a search on the number of patients. Then, I have 4 fields that the usr can fill in and search for a specific patient. Then, when an existing patient is selected some values are passed to a main form. If a patient is not found, the data is passed also to the main form to create a new patient, based on those values...
I'm using Rails 3.2 and Ransack. Here's an example of the parameters returned on one basic search:
Parameters: {"utf8"=>"✓", "authenticity_token"=>"gT8RPTlPiO6Wf3oLcU5+qSzVOZTjBZyX1Y0qNijT5oo=", "q"=>{"nid_cont"=>"2/14", "province_id_eq"=>"2", "district_id_eq"=>"2", "facility_id_eq"=>"146"}}
Then, on patient controller I have this code:
def patient_samples
#search_patients = Patient.includes(:gender, :province, :district, :facility).search(params[:q])
#patients = #search_patients.result
respond_to do |format|
format.html
format.js
format.json { render json: #patients }
end
end
This code is run when I open the modal and it returns all existing patients. Then, the user is also able to do the search that will only returns the respective rows.
When I select one of the existing patients, I can get all values from it and all the related models, for example:
patient.facility.printer_type
But when the search doesn't find a patient, I would also like to search the printer_type from the facility that I choose on the search parameters.
What I would like to do is to access one of the q: values, in this case
"facility_id_eq" => "146"
And then do something like:
#facility = Facility.find("146")
#facility.printer_type
But I can't seem to be able to access that value... I've read a lot of similar questions here in Stackoverflow, I've read the gem docs on github, I've tried several things, but haven't been able to do it...
I know it's a simple solution, but I'm blocked on it :(
Can you help me?
You can access that value with
facility_id = params[:q]['facility_id_eq']
#facility = Facility.find(facility_id)

How do I perform multiple modifications and save a has_many relationship

class Company < ActiveRecord::Base
has_many :users
end
The user hits on Company->Users href link and assuming it shows 3 users for a certain company.
I would want to set user.age (an integer) for all the users and press save. How do I do this in my controller / view code?
We usually have an Edit link against each User to modify its details, but I would like to set age information for all users.
Use a form_tag to submit to an arbitrary controller action set up specifically for editing multiple users (not one of your user scaffold methods). Then, add one fields_for tag per user inside of the form you created, each with a field for the age attribute. When submitted, you can simply iterate over the user params in the controller to manipulate your users.

Correct Rails way to CRUD extra attributes on link table

I have an extra position attribute on my many-to-many link table. Its purpose is to define hand-ordered position of an Item in a Group. The link model is called ItemGroupMembership.
I am allowing the user to edit this by jQuery UI sortables in a Backbone application.
What is the correct way to update this attribute. Do I treat the link table like a regular model and have a item_group_memberships_controller?
How are Item's assigned to Groups in the first place?
This should be done in the item_group_memberships_controller.
So,
class ItemGroupMembershipsController < Applicationontroller
def create
#create the relationship, passing in :position
end
def update
#update the relationship by updating position
end
end

Devise/CanCan - Restricted Content

Building a rails B2B application that will have various users. I'm pretty clear on restricting access for internal staff using Devise and CanCan but I want to be able to give suppliers and customers their own login as well. Customer will be fairly simple, however, I want to ensure the supplier (label) login enables them to view and amend their own product and sales data only.
The model is roughly:
User (as setup by Devise)
Label [has_many releases]
Release [belongs_to label / has_many products]
Product [belongs_release / has_many tracks]
Track [belongs_product]
I'm guessing I could add in a label_id field on the user model and associate that way but I need internal users (and customers) to have access to view all label data. I also need to allow a label to have many users.
Would it simply be a case of defining a 'label' role via Cancan that enforces the use of a label_id in the the views? If that's the correct approach how do I then lock down the content to that label_id in my controllers/views? Role based if statements?
Thanks in advance!
What you'd first have to do is define some CanCan roles, like supplier, customer and staff, and then create an interstitial controller to handle the forking:
class CheckingController < ApplicationController
def index
#path = case user.role
when 'supplier'
supplier_path
when 'customer'
customer_path
when 'staff'
staff_path
else
admin_sign_in_path #or whatever
end
redirect_to #path
end
end
Then in your routes.rb file you can send users to either the root or index action of your controller by first sending them to CheckingController#index which will redirect based on your CanCan roles.

Resources