I am sending an invitation to a new user using Devise Invitable. I have a related table to Users called Organizations, with a belongs_to/has_many relationship. When the new user goes to accept the invitation, it states that there must be an organization specified. How would I go about making sure the user is assigned to the inviting user's organization automatically, so that the database is updated and the invitation can be accepted?
Thank you!
Modeling after the invitation token as a hidden field, I added
<%= f.hidden_field :plan_id, :value => 1 %>
<%= f.hidden_field :organization_id, :value => 1 %>
to the edit.html.erb invitations view. This works to submit the information I'm looking for, but I'm worried that it is not secure, as those parameters could be adjusted. I also tried adding the following to the edit control in the invitations controller, but it did nothing.
resource.plan_id = 1
resource.organization_id = 1
I have a similar setup, have you tried something like this in the create section of your invitations controller?
This approach works for me, but you'll need to override the default invitations controller do it this way.
def create
#invited_user = User.invite!({:email => "bob#someone.com"}, current_user)
#invited_user.update(organization: current_organization)
...
end
I have current_organization defined in my application_controller.rb file as:
def current_organization
#current_organization ||= current_user.organization
end
if you use devise invitable, Overwrite your invitations controller's new and update actions.
In the new action associate the new user to the group, in the update action permit the foreign key and you should be good to go.
Related
I'm just starting to learn Rails and I'm currently working on a watered down Facebook clone. I'd like to know what exactly my build method that I'm including in my form_for helper is doing. This is taken from The Ruby On Rails Tutorial by Michael Hartl where we did something similar, but with Twitter followers instead of friend requests. I couldn't wrap my head around it then, and I'm still having trouble now.
Here is the form that I'm using when a user sends a friend request to another user. This is a form partial rendered from #users (hence the user.id)
<%= form_for(current_user.active_relationships.build) do |f| %>
<div><%= hidden_field_tag :friend_id, user.id %></div>
<%= f.submit "Send Friend Request" %>
<% end %>
This passes to my Friendships controller...
def create
#user = User.find(params[:friend_id])
current_user.send_friend_request(#user)
redirect_to current_user
end
Which makes a call to send_friend_reqeust...
def send_friend_request(other_user)
friend_requests << other_user
end
My User model has_many :friend_requests, through: :active_relationships
It works fine, but I started questioning what current_user.active_relationships.build in my form_for helper was even doing. To my (very) untrained eye, it looks like the form is passing a hidden value of friend_id which the Friendships controller then uses to find the User database record associated with that ID.
If all that my form is doing is submitting a hidden User ID, then what is the point of the build method? I know it must do something since removing it breaks my program.
Any help is appreciated. Thank you!
It is an intermediary model between User and FriendRequest models.
By using method BUILD you create a new ActiveRelationship and through that then you can create new FriendRequest.
User >> ActiveRelationship >> FriendRequest
As a total Ruby noob i need to do a simple thing but doing it the ruby way is not clear for me.
What is want to do is the following:
I have a devise User model with a one to one association "Account"
In the devise registration view i want to add extra form fields for this account, and that is where i am stuck.
It seems i cannot add the account fields to the view
for example this will not work:
# address is a field of Account
<%= f.text_field :address %>
How can i bring the Account model into the scope? Or is there a way to do something like this
<%= f.text_field :account['address'] %>
I have really no clue how to add account into scope or how i can access the User assoc Account properly.
Thx for the help
You need to use accepts_nested_attributes_for :account to able to add parameters from registration form.
Then whitelist these parameters by overriding devise method configure_permitted_parameters.
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up, keys: [account_attributes: [:address]])
end
You might need to change which parameters needs to be whitelisted.
Then in view, you need to use fields_for like
f.fields_for(:addresss) do |address_fields|
<%= address_fields.text_field :address %>
end
Hopefully, this solves the problem. Try to search about nested attributes if something doesn't work.
you need to override devise RegistrationsController from there modify on create method to build account record when user successfully sign up
I'm trying to user Devise invitable to add multiple users at once. Basically when someone creates an account, the first thing they'll want to do is add a bunch of users using the invitable form...
just not sure how to duplicate fields in the form and have them send a create request for each entry.
Thanks in advance!
This is how I would do it.
Provide a text area that accepts a comma-separated email list. Define
a new action that sends an invitation to each email in this list.
Lets assume a User model and a users controller for this example.
Define a route for the batch_invite action.
resources :users do
collection do
post 'batch_invite'
end
end
Define the batch_invite action in the users_controller
def batch_invite
#Validate the user_emails field isn't blank and emails are valid
params[:user_emails].split(",").each do |email|
User.invite!(:email => email)
end
#redirect_to appropriate path
end
A form that accepts a comma-separated list of emails in a textarea.
<%= form_tag batch_invite_users_path, :method => :post do %>
<%= label_tag "Email ids of people you'd like to invite." %>
<%= text_area_tag :user_emails %>
<%= submit_tag "Invite!" %>
<% end %>
A couple of notes :
If you like your controller skinny, you could move the logic to the model, for instance, by creating a send_batch_invitations method in your User model and pass the params[:user_emails] as an argument to that method from the users controller.
Since the method that sends the invitations could take sufficient time to complete, I would suggest you assign this task to a background job processor, such as delayed_job or resque.
There are railscasts that demonstrate the usage of these two background job processors.
I'm trying to user Devise invitable to add multiple users at once. Basically when someone creates an account, the first thing they'll want to do is add a bunch of users using the invitable form...
just not sure how to duplicate fields in the form and have them send a create request for each entry.
Thanks in advance!
This is how I would do it.
Provide a text area that accepts a comma-separated email list. Define
a new action that sends an invitation to each email in this list.
Lets assume a User model and a users controller for this example.
Define a route for the batch_invite action.
resources :users do
collection do
post 'batch_invite'
end
end
Define the batch_invite action in the users_controller
def batch_invite
#Validate the user_emails field isn't blank and emails are valid
params[:user_emails].split(",").each do |email|
User.invite!(:email => email)
end
#redirect_to appropriate path
end
A form that accepts a comma-separated list of emails in a textarea.
<%= form_tag batch_invite_users_path, :method => :post do %>
<%= label_tag "Email ids of people you'd like to invite." %>
<%= text_area_tag :user_emails %>
<%= submit_tag "Invite!" %>
<% end %>
A couple of notes :
If you like your controller skinny, you could move the logic to the model, for instance, by creating a send_batch_invitations method in your User model and pass the params[:user_emails] as an argument to that method from the users controller.
Since the method that sends the invitations could take sufficient time to complete, I would suggest you assign this task to a background job processor, such as delayed_job or resque.
There are railscasts that demonstrate the usage of these two background job processors.
I want to be able to give codes to potential users in the form of email links (e.g. mysite.com/signup?beta=rapunzel)
When someone clicks on the link, it populates a hidden_field with the value (will just using :params[:beta] work?)
Then before it creates the user it validates by checking against another table where I have different beta code.
Then goes ahead and stores which code or maybe just the beta.id.
Suggestions? A plugin already exists?
Thanks.
When your user hits mysite.com/signup, the action associated with that route will have the value "rapunzel" stored in params[:beta]. You can pass that onto your view by assigning it into an instance variable (#beta), pass it back to your user controller through your hidden field as planned, and compare it there to your table before saving the user object.
Or you could only allow your user to get to the signup page at all if they're passing in a valid beta code, in which case you won't need any special form fields:
def signup
unless BetaCode.find_by_code(params[:beta])
flash[:notice] = "You can't sign up without a beta code!"
redirect_to root_path
end
end
What parameters you get out of your URL will depend on how your routes are set up. With your current route you would get:
params[:beta] = "rapunzel"
If you specify your route as:
map.connect '/signup/:beta', :controller => 'signup', :action => 'beta'
you could send them a link like: mysite.com/signup/rapunzel instead and you would get the beta parameter the same as before.
To get the beta field onto the form just include it as a hidden field on the form page template.
In the controller put something like:
#beta_id = params[:beta]
Then in the view template put:
hidden_field_tag 'beta', #beta_id
Then when they signup and create a proper id you'll probably want to hook in an association from their row in the user's table to the row containing the beta id in the "beta" table. This could be a has_one association on the beta table if you only wanted to allow a single user to register with each beta id, or a has_many if multiple people could sign up with it.
I would have done this with a validation.
class User < ActiveRecord::Base
validate_on_create {|r|
beta_code = BetaCode.find_by_code(r.beta_code)
beta_code && beta_code.destroy ||
r.errors.add(beta_code, "is invalid")
}
attr_accessor :beta_code
end
In your form:
<% form_for(#user) do |f| %>
# fields...
<%= f.text_field :beta_code %>
<% end %>
This assumes that you have a BetaCode model whose table contains a list of beta codes.