2016-08-23 2 views
1

Я не уверен, способ, которым я лечу, это проблема, или ERB.Rails 4 - флеш-предупреждение с открытым текстом и ERB

Сейчас, когда пользователь регистрируется, я отправил электронное письмо активации. Если они не активированы и попытаются войти в систему, им будет предложено «Извините, вы не авторизованы». Я хочу изменить его так, чтобы он предлагал им повторно отправить сообщение по электронной почте.

SessionsController

class SessionsController < ApplicationController 
    def new 
    end 

    def create 
    user = User.find_by(email: params[:session][:email].downcase) 
    if user && user.authenticate(params[:session][:password]) 
     if user.activated? 
     log_in user 
     params[:session][:remember_me] == '1' ? remember(user) : forget(user) 
     redirect_back_or user 
     else 
     message = "Account not activated. " 
     message += "Check your email for the activation link, or click" + <%= link_to "here", :controller => :user, :action => :resend_email %>+ "to have it resent!" 
     flash[:warning] = message 
     redirect_to root_url 
     end 
    else 
     flash.now[:danger] = 'Invalid email/password combination' 
     render 'new' 
    end 
    end 

    def destroy 
    log_out if logged_in? 
    redirect_to root_url 
    end 

end 

В контроллере Users Я сделал функцию 'resend_email'. По сути, просто большинство созданных, поэтому немного избыточно.

UsersController

class UsersController < ApplicationController 
    before_action :logged_in_user, only: [:index, :edit, :update, :destroy] 
    before_action :correct_user, only: [:edit, :update] 
    before_action :admin_user,  only: :destroy 

    def index 
    @users = User.where(activated: true).paginate(page: params[:page]) 
    end 

    def show 
    @user = User.find(params[:id]) 
    redirect_to root_url and return unless @user.activated? 
    end 

    def new 
    @user = User.new 
    end 

    def create 
    @user = User.new(user_params) 
    if @user.save 
     @user.send_activation_email 
     flash[:info] = "Please check your email to activate your account." 
     redirect_to root_url 
    else 
     render 'new' 
    end 
    end 

    def resend_email 
    @user.send_activation_email 
    flash[:info] = "Please check your email to activate your account." 
    redirect_to root_url 
    else 

    def edit 
    @user = User.find(params[:id]) 
    end 

    def update 
    @user = User.find(params[:id]) 
    if @user.update_attributes(user_params) 
     flash[:success] = "Profile updated" 
     redirect_to @user 
    else 
     render 'edit' 
    end 
    end 

    def destroy 
    User.find(params[:id]).destroy 
    flash[:success] = "User deleted" 
    redirect_to users_url 
    end 

    private 

    def user_params 
     params.require(:user).permit(:name, :email, :password, 
            :password_confirmation) 
    end 

    # Before filters 

    # Confirms a logged-in user. 
    def logged_in_user 
     unless logged_in? 
     store_location 
     flash[:danger] = "Please log in." 
     redirect_to login_url 
     end 
    end 

    # Confirms the correct user. 
    def correct_user 
     @user = User.find(params[:id]) 
     redirect_to(root_url) unless current_user?(@user) 
    end 

    def admin_user 
     redirect_to(root_url) unless current_user.admin? 
    end 

end 

Я попытался модифицировать «сообщение» в нескольких различных версиях и каждый раз, когда я получаю ответ, похожий на

/home/ubuntu/workspace/sample_app/app/controllers/sessions_controller.rb:16: syntax error, unexpected '<' <%= link_to "here", :controlle...^/home/ubuntu/workspace/sample_app/app/controllers/sessions_controller.rb:16: syntax error, unexpected ',', expecting keyword_end ...o "here", :controller => :user, :action => :resend_email %> ...^/home/ubuntu/workspace/sample_app/app/controllers/sessions_controller.rb:16: syntax error, unexpected '>' ...r, :action => :resend_email %> ...^

Я получил этот синтаксис из предыдущего опыта , и люди с похожими потребностями, чтобы мои.

Так мне интересно, что это лучший способ сделать это, без драгоценных камней (я нашел Придумайте функциональность, но я стараюсь, чтобы узнать, как сделать это самостоятельно)

Я также читал, что иногда ERB и обычный текст работают неправильно. Однако, я также получаю сообщение об ошибке с сообщением только <%= link_to "here", :controller => :user, :action => :resend_email %>.

Я не уверен, нужны ли какие-либо другие контроллеры.

EDIT INFO

Оставляя оригинал для других людей с вопросом. После прочтения того, что указано в его ответе ниже, я изменил некоторые вещи.

Изменения SessionsController

link = view_context.instance_exec do 
    ERB.new("<%= link_to 'here', :controller => :users, :action => :resend_activation %>").result(binding) 
end 
message = "Account not activated. " 
message += "Check your email for the activation." 
message += link # This is for demo purposes, just needed an output 

Контроллер пользователя

Защиту resend_activation @user = User.find (Params [: адрес электронной почты]) @ user.send_activation_email вспышки [: Информация ] = «Пожалуйста, проверьте свою электронную почту, чтобы активировать свою учетную запись». redirect_to root_url конец

Частичный вид для предупреждения

<% flash.each do |message_type, message| %> 
    <%= content_tag(:div, sanitize(message), class: "alert alert-#{message_type}") %> 
    <% end %> 

До этого момента я сейчас видим ссылку я ожидал, и моя проблема, когда я нажимаю его.

Couldn't find User with 'id'= - Я пробовал разные виды использования User и даже сказал, что он повторно выполняет поиск по параметрам электронной почты.

Так что я попытался обновить свои маршруты в

Маршруты

Rails.application.routes.draw do 

    root 'static_pages#home' 
    get '/home', to: 'static_pages#home' 
    get '/help', to: 'static_pages#help' 
    get '/about', to: 'static_pages#about' 
    get '/contact', to: 'static_pages#contact' 
    get '/signup', to: 'users#new' 
    post '/signup', to: 'users#create' 
    get '/login', to: 'sessions#new' 
    post '/login', to: 'sessions#create' 
    delete '/logout', to: 'sessions#destroy' 
    resources :users 
    resources :account_activations, only: [:edit] 
    post '/resend_activation:email' => 'account_activations#resend_activation', 
             :constraints => { :email => /[^\/]+/ } 
    # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html 
end 

который сделал прогресс (я думаю), и теперь мне подсказывает «не прибудете ресурс не найден». Я занимаюсь исследованием того, когда использовать get vs post, и я думал, что поступил правильно. Но почему он пытается ссылаться на этот путь, если сразу после отправки электронной почты он должен вернуться к root_url?

Еще раз спасибо.

Update # 2:

Я был в состоянии получить ошибки, чтобы остановить путем добавления в маршрутных переключателях и изменения моего sessions_controller к

def create 
    user = User.find_by(email: params[:session][:email].downcase) 
    if user && user.authenticate(params[:session][:password]) 
     if user.activated? 
     log_in user 
     params[:session][:remember_me] == '1' ? remember(user) : forget(user) 
     redirect_back_or user 
     else 
     message = "Account not activated. " 
     message += "Check your email for the activation." 
     message += " #{view_context.link_to "Resend Activation E-Mail", { action: "resend_activation", 
     controller: "account_activations", email: user.email }, method: :post}" 
     flash[:warning] = message 
     redirect_to root_url 
     end 
    else 
     flash.now[:danger] = 'Invalid email/password combination' 
     render 'new' 
    end 
    end 

Но теперь нет электронной почты гаснет , все просто возвращается к логину.

heroku logs --tail

Сообщает мне

Heroku Журналы

2016-08-24T09:44:48.990703+00:00 app[web.1]: I, [2016-08-24T09:44:48.990609 #5] INFO -- : [8cfcee3c-133c-489e-8877-523578821d67] Started GET "/resend_activation/[email protected]" for 100.15.65.126 at 2016-08-24 09:44:48 +0000 
2016-08-24T09:44:48.992317+00:00 app[web.1]: I, [2016-08-24T09:44:48.992217 #5] INFO -- : [8cfcee3c-133c-489e-8877-523578821d67] Processing by StaticPagesController#home as 
2016-08-24T09:44:48.992394+00:00 app[web.1]: I, [2016-08-24T09:44:48.992349 #5] INFO -- : [8cfcee3c-133c-489e-8877-523578821d67] Parameters: {"email"=>"[email protected]"} 
2016-08-24T09:44:48.997712+00:00 app[web.1]: I, [2016-08-24T09:44:48.997648 #5] INFO -- : [8cfcee3c-133c-489e-8877-523578821d67] Rendering static_pages/home.html.erb within layouts/application 
2016-08-24T09:44:48.999032+00:00 app[web.1]: I, [2016-08-24T09:44:48.998965 #5] INFO -- : [8cfcee3c-133c-489e-8877-523578821d67] Rendered static_pages/home.html.erb within layouts/application (1.1ms) 
2016-08-24T09:44:49.010260+00:00 app[web.1]: I, [2016-08-24T09:44:49.010186 #5] INFO -- : [8cfcee3c-133c-489e-8877-523578821d67] Rendered layouts/_shim.html.erb (0.4ms) 
2016-08-24T09:44:49.010516+00:00 app[web.1]: I, [2016-08-24T09:44:49.010461 #5] INFO -- : [8cfcee3c-133c-489e-8877-523578821d67] Rendered layouts/_shim.html.erb (0.0ms) 
2016-08-24T09:44:49.010642+00:00 app[web.1]: I, [2016-08-24T09:44:49.010591 #5] INFO -- : [8cfcee3c-133c-489e-8877-523578821d67] Rendered layouts/_headElement.html.erb (7.6ms) 
2016-08-24T09:44:49.020206+00:00 app[web.1]: D, [2016-08-24T09:44:49.020136 #5] DEBUG -- : [8cfcee3c-133c-489e-8877-523578821d67] User Load (1.8ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2 [["id", 103], ["LIMIT", 1]] 
2016-08-24T09:44:49.020630+00:00 app[web.1]: I, [2016-08-24T09:44:49.020565 #5] INFO -- : [8cfcee3c-133c-489e-8877-523578821d67] Rendered layouts/_header.html.erb (3.8ms) 
2016-08-24T09:44:49.025024+00:00 app[web.1]: I, [2016-08-24T09:44:49.024957 #5] INFO -- : [8cfcee3c-133c-489e-8877-523578821d67] Rendered layouts/_footer.html.erb (0.7ms) 
2016-08-24T09:44:49.025337+00:00 app[web.1]: I, [2016-08-24T09:44:49.025273 #5] INFO -- : [8cfcee3c-133c-489e-8877-523578821d67] Completed 200 OK in 33ms (Views: 26.1ms | ActiveRecord: 1.8ms) 

Он находит элемент, и делает это, но уже не по почте. Я думаю, это из-за того, что мне нужно было установить маршрут, чтобы он «работал»?

+0

Вы когда-нибудь решали это? –

+0

см. Ответ ниже –

ответ

2

С помощью следующего кода:

message += 
     "..."" + 
     <%= link_to "here", :controller => :user, :action => :resend_email %> + 
     "..." 

Вы пытаетесь использовать Еврорадио теги в обычном рубина - это не будет работать. Вы можете использовать ERB только в шаблонах.

Обычно я бы посоветовал использовать стандартную интерполяцию строк Ruby's #{}, но на самом деле это не решит проблему.

link_to доступен только вид по умолчанию, хотя вы можете получить к нему доступ через view_context объекта:

link = "#{view_context.link_to 'here', :controller => :user, :action => :resend_email}" 

Кстати, можно использовать Еврорадио в контроллерах, если вы собираете сам:

link = ERB.new("<%= view_context.link_to(...) %>").result(binding) 

Вы можете изменить переменные/методы, доступные для ERB, вызвав его в другом контексте, т.е.:

link = view_context.instance_exec do 
    ERB.new("<%= link_to(...) %>").result(binding) 
end 

Это работает со стандартной #{} интерполяции строк тоже:

link = view_context.instance_exec do 
    "#{link_to(...)}" 
end 

Стоит отметить, что если вы сделаете заказ HTML строку в контроллере (например, вы здесь делаете со вспышкой), когда отображать текст на представлении вам нужно будет добавить некоторые специальные методы, чтобы сделать HTML дисплей в качестве реального HTML:

# in controller 
flash[:test] = "<span>some html</span>" 

# in view 
<%= raw flash[:test].html_safe %> 

Таким образом, только текст some html будет отображаться, а не всю строку <span>some html</span>

Там причина raw и html_safe необходимо, и это потому, что печать HTML имеет риски безопасности и Rails разработан, чтобы сделать его более трудным.

Скажите, что ваш пользователь устанавливает свое имя пользователя как "<script>alert("hacked")</script>", и эта строка каким-то образом превращает его в страницу как истинный html. Вы бы только разоблачили своих пользователей XSS (Cross Site Scripting), которые вы не хотите делать. Поэтому убедитесь, что при использовании raw <string>.html_safe вы являетесь не, отображая что-нибудь созданное пользователем.

+0

Большое спасибо за всю вашу информацию, вы привели меня на гусиную погоню, которая у меня очень близко. Я не знал о html_safe (или дезинфицирующую функцию, которую я нашел связанной). Теперь я совсем рядом, если вы можете взглянуть на обновление, которое я собираюсь опубликовать, я бы очень признателен. – DNorthrup

0

Причина, почему ваш маршрут говорит вам, что id = nil потому, что ваш :activation_token в этом маршруте id и он не хранится в базе данных, он создается практически с attr_accessor. Вместо этого сохраните :activation_token в качестве столбца в базе данных.

Смежные вопросы