I want to send multiple invitations at a time using devise-invitable gem.
new.html.erb
<h2>
<%= t "devise.invitations.new.header" %>
</h2>
<%= form_for resource, :as => resource_name, :url => invitation_path(resource_name), :html => {:method => :post} do |f| %>
<%= devise_error_messages! %>
<div>
<% resource.class.invite_key_fields.each do |field| -%>
<p><%= f.label field %><br />
<%= f.email_field field, placeholder: "Invitation email" %></p>
<% end -%>
<%= f.collection_select(:role_id, Role.all, :id, :role_name, :prompt => true) %>
</div>
<p>
<%= f.submit t("devise.invitations.new.submit_button") %>
</p>
<% end %>
my controller:-
class Users::InvitationsController < Devise::InvitationsController
def create
exit
if params[:user][:email]== "" || params[:user][:role_id] == ""
flash[:alert]="Please enter email first and Select any role for invitees"
redirect_to new_user_invitation_path
else
if User.invite!(:email => params[:user][:email], :company_id => current_user.id, :type => 'Employee', :role_id => params[:user][:role_id])
flash[:notice]="Invitation is send successfully."
redirect_to new_user_invitation_path
else
flash[:alert]="Invitation is not send."
redirect_to new_user_invitation_path
end
end
end
end
I think one solution is to pass comma separated emails in invite method but how can I pass it? I really don't know how.
If you have any other solution then please tell me.
Thanks.
i trouble with this problem but finally i got solution to send multiple invitation email at a time.
below i explain my code that how i become possible this.
here is my html view.
new.html.erb
<h2>
<%= t "devise.invitations.new.header" %>
</h2>
<%= form_for resource, :as => resource_name, :url => invitation_path(resource_name), :html => {:method => :post} do |f| %>
<%= devise_error_messages! %>
<div>
<% resource.class.invite_key_fields.each do |field| -%>
<%= f.label field %><br />
<%= f.email_field field, name: "user[email][]", placeholder: "Invitation email", required: true %></p>
<div id="createNewTextbox" >
</div>
<a id="btnLinkCreate" href="#" onClick="create_new();">
+ INVITE MORE
</a>
<% end -%>
</div>
<p>
<%= f.submit t("devise.invitations.new.submit_button") %>
</p>
<% end %>
in this i take one text-box by-default with name : "user[email][]" (it is important because using this rails automatically create email array and send in params whene you submit form )
i also generate dynamic text-box using JavaScript and it will create below div when click on invite more link button :
<div id="createNewTextbox" >
</div>
<a id="btnLinkCreate" href="#" onClick="create_new();">
+ INVITE MORE
</a>
here is my dynamic text-box code of JavaScript.
$('#createNewTextbox').append('<input type="email" id="email'+i+'" name="user[email][]" placeholder="Invitation email" required/>');
now you can see that i give same name to dynamic text-box (name="user[email][]"), so rails automatically create hash array like this:
"user" => { "email" => { "email-1","email-2","email-3"... } }
now this hash array is pass in create method in which we fetch every email from params and give it to invite method to send the invitation.
my controller :-
class Users::InvitationsController < Devise::InvitationsController
def create
params[:user][:email].each do |email|
User.invite!(:email => email)
end
end
end
thats it...
if still you have any query then tell comment me.
Related
In my RoR application I have a form whereby users can search for their contacts by first name and select the ones that they want to send an email to. My problem is that after searching for say "Tom", and selecting the checkbox for "Tom", if they then reset the search to display all check boxes "Tom" is no longer selected.
Can someone please tell me how this can be sorted?
The code in the view is:
<div class="panel-body">
<%= form_tag '/emails/contact_search', :method => 'get' do %>
<p>
<%= text_field_tag :search_string, params[:search_string], :placeholder => "Search by firstname" %>
<%= submit_tag "Search" %>
</p>
<% end %>
<%= form_for(#email) do |f| %>
<fieldset>
<div class="form-group">
<label>From Email Address</label></br>
<% #useraccounts.each do |useraccount| %>
<%= f.radio_button :account_id, useraccount.account_id, :checked => false %>
<%= f.label :account_id, useraccount.account.email, :value => "true" %><br>
<% end %>
</div>
<div class="form-group">
<label>Contacts</label></br>
<%= f.collection_check_boxes :contact_ids, #contacts, :id, :fullname, checked: #selected_contact_ids %>
</div>
<div class="form-group">
<label>Groups</label></br>
<%= f.collection_check_boxes :group_ids, Group.where(user_id: session[:user_id]), :id, :name ,{ prompt: "name" } %>
</div>
<div class="form-group">
<label>Attachment</label>
<%= f.file_field :attachment, :size => 42 %><br>
</div>
<div class="actions">
<%= f.submit "Continue", {:class => 'btn btn-primary '} %>
<%= render "/error_messages", :message_header => "Cannot save: ", :target => #email %>
</div></br>
</fieldset>
<% end %>
</div>
The controller code for the search is:
def contact_search
#email = Email.new(session[:email_params])
#email.current_step == session[:email_step]
#useraccounts = Useraccount.where(user_id: session[:user_id])
#contacts = Contact.contact_search(params[:search_string])
if #contacts.empty?
flash[:notice] = "There are no emails with that subject"
#contacts = Contact.all
end
render :action => "new"
end
private
def email_params
params.require(:email).permit(:subject, :message, :account_id, { contact_ids: [] }, { group_ids: [] }, :attachment)
end
And in the model:
def self.contact_search(search_string)
self.where("firstname LIKE ?", search_string)
end
I cannot work out how to keep a checkbox selected after a user then searches for something else or resets the search, can someone please shed some light on how this can be achieved?
This seems to be one of those obscure and badly documented features of Rails. What has to be done is pass an array if ids to be checked into the checked parameter
= f.collection_check_boxes :contact_ids, #contacts, :id, :fullname, checked: #selected_contact_ids
and then check boxes with items of id 1, 2 and 3 will be checked. You will need to pass this array obviously from the controller somehow. E.g.
#selected_contact_ids = email_params.fetch(:contact_ids, [])
Firstly, I would like to describe what I am going to do. So, my application is set of tasks (eg. exercises depend on writing computer program) which user it available to send solutions through form and server will have compiled it and return results of process.
My problem is that I have model Solution which is presented below:
Solution(id: integer, exercise_id: integer, code: string, user_id: integer,
created_at: datetime, updated_at: datetime, language_id: integer)
and exercise_id, user_id, language_id are foreign keys and postgresql return error that it couldn't be null values...
The form which I use to send this information looks like below:
<fieldset style="add">
<legend>Send solution</legend>
<%= form_for [#user, #exercise, #solution], url: exercise_solutions_path, :html => { role: "form" } do |f| %>
<div class="form-group">
<%= f.label "Source code" %>
<br>
<%= f.text_area :code %>
</div>
<div class="form-group">
<%= f.label "Programming language" %>
<br>
<%= f.select(:language_id, available_lang) %>
</div>
<div class="form-group">
<%= f.submit "Send", :class => "btn btn-default" %>
</div>
<% end %>
</fieldset>
Frankly speaking I don't how to include more information such as user.id or exercise.id. Params look like:
#_params
{"utf8"=>"✓", "authenticity_token"=>"abwhTn3KrVneli0pCVccoWHyzlI7cRTFK5Wo7DdYRK+lL4GwZ8jUPqdzn8ZznCHsWTkfDAFS2RP6gTkWuk33iw==", "solution"=>{"code"=>"ds", "language_id"=>"C++"}, "commit"=>"Wyślij", "controller"=>"solutions", "action"=>"create", "exercise_id"=>"1"}
SolutionController
class SolutionsController < ApplicationController
def index
#solutions = Solution.last(20)
end
def new
#solution = Solution.new
end
def create
#solution = Solution.new(solution_params)
if #solution.save
redirect_to #solution
else
render :new
end
end
def edit
#solution = Solution.find(params[:id])
if #solution.update(solution_params)
redirect_to #solution
else
render :edit
end
end
def destroy
end
private
def solution_params
params.require(:solution).permit(:language_id, :code)
end
end
Edit:
<fieldset style="add">
<legend>Send solution</legend>
<%= form_for [#user, #exercise, #solution], url: exercise_solutions_path, :html => { role: "form" } do |f| %>
<div class="form-group">
<%= f.label "Source code" %>
<br>
<%= f.text_area :code %>
</div>
<div class="form-group">
<%= f.label "Programming language" %>
<br>
<%= f.select(:language_id, available_lang) %>
</div>
<div class="form-group">
<%= f.hidden_field :exercise_id, value: #exercise.id %>
<%= f.hidden_field :user_id, value: #user.id %>
<%= f.submit "Send", :class => "btn btn-default" %>
</div>
<% end %>
</fieldset>
You could 1) add hidden_fields in your form to set the missing attributes:
<div class="form-group">
<%= f.hidden_field :exercise_id, value: #exercise.id %>
<%= f.hidden_field :user_id, value: #user.id %>
<%= f.submit "Send", :class => "btn btn-default" %>
</div>
Make sure to add these attributes to the solution_params permitted parameters:
def solution_params
params.require(:solution).permit(:language_id, :code, :exercise_id, :user_id)
end
A better idea would be to manually set the exercise and user in the controller and leave your solution_params as is. That way you're not allowing the exercise and user to be set by mass assignment, which could be spoofed.
So instead do 2) in your controller:
def create
#solution = Solution.new(solution_params)
#solution.exercise_id = params[:exercise_id]
#solution.user_id = params[:user_id]
if #solution.save
redirect_to #solution
else
render :new
end
end
I'm assuming that :exercise_id and :user_id are in the URL. If not add them as hidden_fields as needed (but this time not on the form object):
<%= hidden_field_tag :user_id, #user.id %>
Also remember to actually select a language_id from the dropdown before you submit the form.
Basically a user is on a project page where they click add new website, which is set out like this
<%= link_to 'Add Asset', new_website_path(:project_id => "#{#project.id}" ), class: 'btn btn-md btn-danger' %>
and then they fill out a form with some data. However I want it so that when they submit that form, that the project id (from the project page they were just on) gets saved under the project_id variable of the website but for some reason this isn't working.
class WebsitesController < ApplicationController
def new
#project = Project.find(params[:project_id])
#website = Website.new(:type => 'Website', :project_id => #project)
end
def create
#website = current_user.assets.build(website_params)
if #website.save
flash[:notice] = "Asset successfully added."
redirect_to(:controller => 'projects', :action => 'show', :id => #website.project_id)
else
render(:action => 'new')
end
end
private
def website_params
params.require(:website).permit(:id, :type,:url, :page_rank, :rev_company ,:social_pages)
end
end
Is there something missing as to why this isn't working? When I check in the console, all the websites I add have a project_id of nil.
When i go onto the form in my browser this is the address:
http://localhost:3000/websites/new?project_id=1
Also, I think it is getting the right project ID because in the form I have a condition which looks at that project ID to see if it is of type website as in:
#views/websites/new.html.erb
<div class="col-md-5 col-md-offset-3">
<div class="panel panel-default newasset">
<div class="panel-heading">
<h3 class="panel-title ptd"><%= "New #{#project.type}" %></h3>
</div>
<div class='panel-body'>
<div class='form group'>
<%= simple_form_for(#website, html: {class: 'form-group' }) do |f| %>
<% if (#project.type == 'Website') %>
<div class="col-xs-4 col-xs-offset-3">
<%= f.input :title, label: 'Website Name' %>
<%= f.input :url %>
<%= f.input :rev_company, label: "Revenue Company" %>
<%= f.input :social_pages, label: "Number of Social Sites" %>
<%= f.input :page_rank %><br />
<div class="form-actions">
<%= f.button :submit, class: 'btn btn-primary' %>
</div>
<% else %>
You should not see this
<% end %>
<% end %>
</div>
</div>
</div>
</div>
Assuming that you are passing :project_id correctly then all you need to permit project_id in website_params method.
def website_params
params.require(:website).permit(:id, :project_id, :type,:url, :page_rank, :rev_company ,:social_pages)
## ^
## Permit project_id
end
Currently, you have not permitted the field project_id which is why its not getting saved.
For Rails 4+ (with Strong Parameters) you need to explicitly specify the fields which you would like to save in database.
#project is an object, and the database must be expecting an integer.
You should call:
#project.id
The best solution anyway is to do:
def new
#project = Project.find(params[:project_id]
#website = #project.websites.build(:type => 'Website')
end
To allow rails to do his magick association through the models if you have declared the: belongs, and has_one/many
I got a backend(Namespace admin) and want to create 4 new database entries with 1 form submit(4 new countries). What I got so far:
In my countries_controller.rb
class Admin::CountriesController < Admin::AdminController
def new
#countries = Array.new(4) { Country.new }
end
end
In my new.html.erb:
<%= form_for [:admin, #countries] do |f| %>
<% #countries.each do |country| %>
<div class="row">
<div class="col-md-6">
<div class="form-group col-md-6">
<%=f.text_field :country, :name, :class => "form-control", :placeholder => "Country 1" %><br>
<%=f.text_field :country, :iso, :class => "form-control", :placeholder => "us" %>
</div></div></div>
<% end %>
<% end %>
But that doesn't work and I get a undefined method model_name for Array:Class error. What is the right way to do this?
form_for is for a single ActiveRecord object, but you're using it with an Array of object :
<%= form_for [:admin, #countries] do |f| %>
Either create a form per object (with each form a save button):
<% #countries.each do |country| %>
<%= form_for [:admin, country] do |f| %>
...
<% end %>
<% end %>
Or see this question for a solution using only one form: Multiple objects in a Rails form
I have these forms:
<%= form_for(#user) do |f| %>
<div>
<%= f.number_field :money, :value => #user.money %>
</div>
<% end %>
and
<%= form_for #product, :url => product_path, :html => { :multipart => true } do |f| %>
<div>
<%= f.label :count, 'How Many product?' %><br />
<%= f.number_field :count, :value => "1" %>
</div>
<div>
<%= f.submit('submit') %>
</div>
<% end %>
is there any way to submit this two at once when clicking submit button ? Thanks!
A service object might be a good way to approach this.
class Order
include ActiveModel::Model
attr_accessor :money, :count
def initialize(user=nil, product=nil)
#user = user
#product = product
#money = user.money
#count = 1
end
def persisted?
false
end
def save
// this code needs to save to db
end
end