How do I add a custom form for my collection_action/controller? - activeadmin

I have the following:
collection_action :new, :method => :post do
begin
user = User.find_by_email(params[:email])
if user
UserPermission.create(:user_id => user.id,
:permission => UserPermission::SUPPORT,
:creator => current_user)
end
rescue ActiveRecord::RecordNotFound
flash[:warn] = 'User not found'
end
redirect_to admin_support_users_path, notice: 'Support user added.'
end
form do |f|
f.inputs do
f.input :email
end
end
action_item only: [:index], :method => :post do
link_to 'Add Support User', new_admin_support_user_path
end
The above works in the sense that no error is thrown. The support users page loads and I'm able to click the Add Support User button. However, 'Support user added.' is immediately shown. The Add Support User button does not take me to a form to enter an email. How do I add/create/use a form that passes an email parameter to my collection_action?
I'm new to activeadmin and documentation is sparse, so any help is appreciated. Thanks.

Figured it out. I'll try to explain as I understand it. And my initial question may have been unclear. The reason I was getting the, 'Support user added.' message is because I was updating the wrong method. The method above should have been the :create controller method, not the :new controller method. :new uses HTTP GET, which is why it would go directly to the redirect. :create accepts an HTTP POST. So, instead, I have the following:
def create
begin
user = User.find_by_email(params[:email])
if user
UserPermission.create(:user_id => user.id,
:permission => UserPermission::SUPPORT,
:creator => current_user)
end
rescue ActiveRecord::RecordNotFound
flash[:warn] = 'User not found'
end
redirect_to admin_support_users_path, notice: 'Support user added.'
end
def new
render 'new.html.arb', :layout => 'active_admin'
end
And this correctly creates a nice looking active admin form, accepting an email parameter.

You just need to add another action--just like a normal resource needs separate actions for create and new. Your 'new' action can render a custom form either inline or in a separate partial, as shown here:
http://www.activeadmin.info/docs/5-forms.html
That said, I'm not sure I understand why you need a custom action. Is this in your User resource file in active admin? If so you can just use the default new user action and include the current user in the form as a hidden variable as the creator. If this is not in your User resource active admin file then you probably need one.

Related

Rails different Devise Mailer layout for the same action

I have a model User that has multiple referenced "profiles". A user can have several of those profiles, and each of those profiles should induce a specific layout in emails. Let's consider the profiles Admin and Worker
For example, in my Devise confirmation controller, I need different layouts depending on the profile the user have. For example, if the user has
Admin profile : render admin template
Worker profile : render worker template
Both : render another template (hybrid)
Therefore I cannot set a layout for the Mailer/Controller, but I need to set it inside the controller action. Let's suppose I have a helper layout_for_user() that can return the layout name for a given user. How would I use it ? For example with Devise mailer ?
class MyDeviseMailer < Devise::Mailer
def confirmation_instructions(record, token, options={})
# whange layout based on `layout_for_user(record)`
#token = token
devise_mail(record, :confirmation_instructions, opts)
end
end
I had to override the devise_mail method
def confirmation_instructions
...
#layout = find_layout_for_user(user)
devise_mail(user, :confirmation_instructions, opts)
end
# Override to include custom layouts
def devise_mail(record, action, opts={})
initialize_from_record(record)
mail(headers_for(action, opts)) do |format|
format.html { render layout: #layout }
end
end

what is the proper way for testing create action in rails RESTfull controller?

I have a users_controller.rb file in which the create action is defined as:-
def create
#user = User.new(user_params)
if current_user.g_admin?
#user.role = 'c_admin'
elsif current_user.c_admin?
#user.role = 'c_user'
end
#user.admin_provisioned = true
authorize #user
respond_to do |format|
if #user.save
format.html { redirect_to authenticated_root_url, notice: 'User was successfully created and email has been sent.' }
format.json { render :show, status: :created, location: #user }
else
format.html { render :new }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
Now, I would like to write test for this method reflecting all the behaviour in this method. I'm completely new to testing, so detailed and standard way for writing test will be accepted as answer. The version to rspec is 3.4. Happy coding.
So the following way you could test this with rspec and capybara. For the fill in part you have to use the input elements that you have on your page.
describe "let an guest create a user account" do
fill_in :user_object, with: "value"
click_button "Save User"
expect(page).to have_content("User was successfully created and email has been sent.")
end
describe "let an guest try to create an account with invalid data" do
fill_in :user_object, with: "invalid value"
click_button "Save User"
expect(page).to_not have_content("User was successfully created and email has been sent.")
expect(page).to have_content("content from the :new page")
end

how do i make diffrent registration form in drupal?

Is there a module that can make different registration forms for different roles during sign up? (ex. each Editor,Main User,Sub User role have different form)
Here's what you should do
start with install profile2-7.x-1.2.tar.gz.
entity-7.x-1.0-rc3.tar.gz once you have profile2 installed -->
enable --> click on configure - (Here you see your profile types
-add as many as you want).
when you add a new one or modify the existing one "Main" make sure you check "Provide a separate page for editing profiles."
4. Now to have different registration, login and password change pages
install and enable profile2_regpath-7.x-1.9.tar.gz
Now visit the profile Types Page again here you should see "UNIQUE REGISTRATION PATH" .. rest is easy ..
There is :)
http://drupal.org/project/autoassignrole
to assign by path you will also need Content Profile:
http://drupal.org/project/content_profile
check out this tutorial on how to pull it off:
http://www.web-a-team.com/blog-post/user-registration-more-one-role
Here is some idea how to solve your question in drupal 7(I think it should work in drupal 6 also). However its not safe since anyone can just change the role they have:
function my_module_form_user_register_form_alter(&$form, &$form_state, $form_id) {
$company_role = $form_state['build_info']['args'][0];
$form['account']['company_role'] = array(
'#type' => 'select',
'#title' => t('Company role'),
'#options' => drupal_map_assoc(array('editor','main user','Sub User')),
'#description' => t('Please select your company role'),
"#empty_option" =>t('- Select -'),
'#weight' => -11, // Add the select box above username that have weight -10
);
switch (strtolower($company_role)) {
case 'editor':
// add extra fields for editor
$form['account']['company_role']['#default_value'] = $company_role;
break;
case 'main user':
// add extra fields for main
$form['account']['company_role']['#default_value'] = $company_role;
case 'sub user';
// add extra fields for 'Sub User'
$form['account']['company_role']['#default_value'] = $company_role;
break;
default:
$form['account']['company_role']['#empty_option'] = t('- Select -');
$company_role = null;// error handling or default case
}
}
If you for example have LDAP in your company you could instead get this information from LDAP(https://www.drupal.org/node/1053748). Then you can be more sure about the role is chosen correctly.

How to check if helper method/variable exists in rspec?

Im still trying to figure out rspec and right now I am using authlogic to handle my users and sessions. I did the usual authlogic stuff like adding the def current_user method to applciation controller, and as a helper method, but how do I access that in my rspec controller file?
Here is my user_sessions_controller_spec.rb:
require 'spec_helper'
require 'authlogic'
describe UserSessionsController do
context "user is already logged in" do
before(:each) do
include Authlogic::TestCase
activate_authlogic
UserSession.create Factory.build(:user)
end
it "should redirect the user to the home page" do
get 'new'
response.should redirect_to(home_path)
end
end
describe "#create" do
context "when the user is not logged in" do
before(:each) do
current_user = nil
end
it "correct authorization should create a new session" do
post 'create', {:login => "afactoryuser", :password => "apass", :password_confirmation => "apass"}
current_user.should_not be_nil
end
end
end
end
when i run rspec it just tells me:
correct authorization should create a new session
undefined local variable or method `current_user' for #<RSpec::Core::ExampleGroup::Nested_1::Nested_2::Nested_1:0x000001017d3410>
so im guessing it is in the rspec context...but how do i know it should be in user-sessions_controller? And am I even testing it correctly?
Insted of current_user in your RSpec, try controller.current_user
If you want to stub current_user method use: controller.stub!(:current_user).and_return(whatever) in before :each
block, but then you will always get whatever if you stub it.

Authlogic edit_password_reset_url in Functional / Integration Tests

I am trying to implement some tests to validate the behavior for Authlogic password resets as explained in http://www.binarylogic.com/2008/11/16/tutorial-reset-passwords-with-authlogic/
I am using Authlogic, Shoulda, Webrat and Factory Girl and here's my test:
require 'test_helper'
class PasswordResetTest < ActionController::IntegrationTest
setup :activate_authlogic
context "A registered user" do
setup do
#reggie = Factory(:reggie)
end
should "not allow logged in users to change password" do
visit signin_path
fill_in 'Email', :with => #reggie.email
fill_in 'Password', :with => #reggie.password
click_button 'Sign In'
assert_equal controller.session['user_credentials'], #reggie.persistence_token
visit change_password_path
assert_equal account_path, path
assert_match /must be logged out/, flash[:notice]
visit signout_path
assert_equal controller.session['user_credentials'], nil
visit change_password_path
assert_equal change_password_path, path
end
should "allow logged out users to change password" do
visit signout_path
assert_equal controller.session['user_credentials'], nil
visit change_password_path
assert_template :new
fill_in 'email', :with => #reggie.email
click_button 'Reset my password'
assert_match /Please check your email/, flash[:notice]
assert !ActionMailer::Base.deliveries.empty?
sent = ActionMailer::Base.deliveries.first
assert_equal [#reggie.email], sent.to
assert_match /Password Reset Instructions/, sent.subject
assert_not_nil #reggie.perishable_token
#TODO
p "Perishable Token #{#reggie.perishable_token}"
assert_match assigns[:edit_password_reset_url], sent.body
end
end
end
In the last 2 lines of the test, I am trying to make sure the link sent out has the right perishable_token and it always comes up different between the printed Perishable Token and the token in the link sent out.
How should I test this behavior?
Thanks, Siva
Careful. Authlogic is magic. Certain operations cause the User object to mutate and when it does, the perishable_token well, perishes (gets regenerated).
I wonder if your visit signout_path is really logging you out. Typically, if your UserSession is RESTful you'd have to issue an HTTP DELETE to the resource to actually delete the session. Just visiting the path (with a GET) won't delete the session unless you have an explicit route for it (mapping e.g. '/logout' to :controller => 'user_sessions', :action => 'destroy')
Change the line in notifier.rb to this:
body :edit_password_resets_url => edit_password_resets_url(user.perishable_token)

Resources