问题
I have a 'Feedback' model whereby a user should be able to request feedback on his/her job performance. I have written basic actions for creating a new feedback request, and the mailer for sending the request to the provider (person who will respond with feedback).
I would like advice from the community on implementing the following:
- Once a new feedback request is created, the email that is sent should contain a link to a form where the provider can input his feedback on the users performance.
- The feedback provider should not be required to log-in or sign-up in any way (i.e. completely external to the application).
- Once submitted, feedback from the provider should be captured in the system.
Now, I have the following ideas to implement it, but am not sure if this is the best way to proceed:
- Generate a unique token upon the creation of a new feedback request. Something like this: Best way to create unique token in Rails?.
- The token should then be entered into 'feedbacks' table.
- Mailer should then generate variable (e.g. @url) which generates link to another controller (let's say 'external_feedback' and action which does not require log-in (e.g. no before_filter :authenticate_user! from Devise).
- That URL should contain a parameter with the token for the specific feedback request.
- The action should be to update the 'feedback' request and a form generated with simple_form.
The whole thing is similar to responding to a questionnaire or survey (like Survey Monkey).
After some research I believe the Friendly ID gem may be useful here. I was also reading Section 8 of http://guides.rubyonrails.org/form_helpers.html and perhaps I need to implement an authenticity_token in the formal sense. What I am really looking for is:
- Is the above approach the generally correct way to go about doing this?
- If so, any specifics on how you would implement it (with or without Friendly ID)?
- Do you know of any gems that exist for generating such URLs/tokens?
Thank you in advance. I am now including the current state of model and controller details:
feedback.rb
# == Schema Information
#
# Table name: feedbacks
#
# id :integer not null, primary key
# user_id :integer
# p_first_name :string(255)
# p_last_name :string(255)
# p_email :string(255)
# goal_id :integer
# u_comment :text
# p_comment :text
# created_at :datetime
# updated_at :datetime
#
class Feedback < ActiveRecord::Base
belongs_to :user
belongs_to :goal
has_many :feedback_attributes
validates_presence_of :p_first_name, :p_last_name, :p_email, :goal_id
end
And this is my mailer:
class FeedbackMailer < ActionMailer::Base
def feedback_request(user, feedback)
@user = user
@feedback = feedback
@url = 'http://thisistheexampleurlforfeedback'
mail(to: @feedback.p_email, subject: "#{@user.first_name} #{@user.last_name} has requested your feedback", from: @user.email)
end
end
回答1:
Add a token field to the feedback model with an index and add a callback to populate it on create e.g. feedback.rb
before_create :add_token
private
def add_token
begin
self.token = SecureRandom.hex[0,10].upcase
end while self.class.exists?(token: token)
end
now add a new route for the providers feedback
resources :feedbacks do
get 'provider'
put 'provider_update' # you might not need this one, if you are happy to use update
end
In your controller make sure they don't get rejected by devise
before_filter :authenticate_user!, except: [:provider, :provider_update]
...
def provider
@feedback = Feedback.find_by token: params[:token]
end
then in the app/views/feedback/provider.html.haml you can use url in simple_form to send it to the correct update location and only provide the input that they should see.
f.inputs :p_comment
Now update your mailer.
@url = provider_feedback_url(@feedback, token: @feedback.token)
You could do something similar to this using friendly id but you would still need to create some sort of unique slug and then use Feedback.friendly.find instead. I think you would want to combine it with a token to ensure it's still the provider giving the feedback - so the only benefit would really be hiding the true id/count. I think you should update p_* fields to provider_* so that the next dev knows what's in it - it's not the 90s!
来源:https://stackoverflow.com/questions/19115929/generating-a-unique-url-with-tokens-in-rails-4-for-an-external-form-response