Одна вещь можно сделать на моем рэпе лирический сайт объяснения, похожа на объяснения (после того как Вы зарегистрированы):
http://dl.getdropbox.com/u/2792776/screenshots/2010-01-17_1645.png
Я хотел бы показать "Подобные" ссылки пользователям, которые не зарегистрированы, и затем, когда незарегистрированный пользователь нажимает "Like", покажите ему лайтбокс с "Входом в систему или Регистром" форма (как Digg / Reddit)
http://dl.getdropbox.com/u/2792776/screenshots/2010-01-17_1650.png
Что лучший способ состоит в том, чтобы выполнить это?
В настоящее время я использую этот подход:
/annotations/:id/vote
(тело POST указывает, любит ли пользователь или "не любит"). vote
Действие контроллера аннотации имеет a require_user
before_filter
это похоже на это:
def require_user
unless current_user
store_desired_location
flash[:notice] = "You'll need to login or register to do that"
redirect_to login_path # map.login '/login', :controller => 'user_sessions', :action => 'new'
return false
end
end
user_sessions#new
похож на это:
def new
@user_session = UserSession.new
respond_to do |format|
format.html {}
format.js {
render :layout => false
}
end
end
Проблема состоит в том, что перенаправление, кажется, не работает правильно по JavaScript:
http://dl.getdropbox.com/u/2792776/screenshots/2010-01-17_1700.png
Как я заставляю это перенаправлять правильно?
Кроме того, действительно ли это - правильный общий подход? Другая мысль, которую я имел, состояла в том, чтобы присоединить другой обработчик к "Подобным" ссылкам в JavaScript, когда было, не вошел в систему пользователь (но я не думаю, что этот метод масштабируется хорошо к другим действиям, что я хотел бы обработать тот же путь),
Нет много причин, чтобы люди догадывались... Вы сказали, что можете найти журнал построения - точное местоположение любого выходного файла будет там. Чтобы убедиться, что вы видите правильный файл журнала сборки, окно вывода в VS будет иметь ссылку на файл, который был создан конкретным запуском сборки:
1>Build log was saved at "file://c:\DevTrees\cppTest\Debug\BuildLog.htm"
1>cppTest - 0 error(s), 2 warning(s)
Если у вас возникли проблемы с интерпретацией, отправьте содержимое.
-121--4716568-Как сказано выше, просто поместите все данные, которые вы хотите получить обратно, в массив и закодируйте их.
<?php
echo json_encode(array(
'html' => $html,
'foo' => $bar,
'bar' => $baz
));
?>
Также, как сказано, вам не нужен json2.js. Можно выполнить синтаксический анализ данных JSON с помощью любой из ajax-функций jQuery, указав тип данных json.
$.ajax({
type: 'POST',
url: 'path/to/php/script.php',
dataType: 'json',
data: 'foo=bar&baz=whatever',
success: function($data) {
var html = $data.html;
var foo = $data.foo;
var bar = $data.bar;
// Do whatever.
}
});
ИЗМЕНИТЬ В значительной степени то, что сказал Хория. Единственный вариант, который я мог бы увидеть, это если бы вы хотели все в том же массиве.
Например:
PHP:
<?php
// You have your comment array sent up as you want as $comments
// Then just prepend the HTML string onto the beginning of your comments array.
// So now $comments[0] is your HTML string and everything past that is your comments.
$comments = array_unshift($comments, $your_html_string);
echo json_encode($comments);
?>
jQuery:
$.ajax({
type: 'POST',
url: 'path/to/php/script.php',
dataType: 'json',
data: 'foo=bar&baz=whatever',
success: function($comments) {
// Here's your html string.
var html = $comments[0];
// Make sure to start at 1 or you're going to get your HTML string twice.
// You could also skip storing it above, start at 0, and add a bit to the for loop:
// if x == 0 then print the HTML string else print comments.
for (var x = 1; x < $comments.length; x++) {
// Do what you want with your comments.
// Accessed like so:
var name = $comments[x].name;
var comment = $comments[x].comment;
var datetime = $comments[x].datetime;
}
}
});
-121--2463759- Здесь можно решить несколько проблем.
Браузеры обычно не разрешают перенаправление на запрос POST.
redirect _ to не сохраняет формат без дополнительного ввода.
Расположение хранилища не сохраняет данные формы.
Все эти проблемы можно решить путем устранения перенаправлений.
Вот как я передал его в прошлом:
Вместо того, чтобы перенаправлять в required_user, рендеринг. Если фильтр перед перенаправляет или визуализирует ожидающее действие, оно отменяется. (Также нет необходимости возвращать значение false). К сожалению, этот маршрут размывает границы контроллера. Но позволяет простой HTML-откат, и предоставляет себе DRYness.
Высокоуровневое представление нового рабочего потока будет выглядеть следующим образом:
Начните с переработки require_user для визуализации шаблона user_sessions#new.
def require_user
unless current_user
flash[:notice] = "You'll need to login or register to do that"
@user_session ||= UserSession.new
respond_to do |format|
format.html {render :template => 'user_sessions/new'}
format.js {
render :template => 'user_sessions/new', :layout => false
}
end
end
end
@ user _ session | | = UserSession.new
обеспечивает возврат ошибок проверки в форму.
Теперь мы должны увеличить ваш шаблон user_session#new, чтобы он мог запомнить действие. Кроме того, если вы планируете использовать lightboxes, это должно быть частично визуализировано соответствующими RJS или new.html.erb.
Сначала мы создадим частичную для создания скрытых полей, сохраняющих данные POST, которые были бы потеряны при перенаправлении:
<% if params[:controller] == "annotations" %>
<% content_for :old_form do %>
<%= hidden_field_tag "annotation[song_id]", params[:annotation][:song_id] %>
<%= hidden_field_tag "annotation[vote]", params[:annotation][:vote] %>
<% end %>
<% end %>
Затем визуализируем частичную в частичном входе, которая займет ваш lightbox:
<%= render :partial => vote_form_replica %>
<% url = params[:controller] == "user_sessions ? user_sessions_url : {} %>
<% form_tag @user_session, :url => url do |f| %>
<%= yield :old_form %>
<%= f.label :user_name %>
<%= f.text_field :user_name %>
<%= f.label :password %>
<%= f.password_field :password %>
<%= submit_tag %>
<%end%>
Пустой хэш для URL в form_tag выглядит как ошибка, но не является. Это обеспечивает разноску данных формы по URL-адресу, по которому была выполнена визуализация формы. На данном этапе должны быть аннотации/: id/vote
Теперь для входа в систему новому фильтру. По существу, он будет делать то, что когда-либо UserExhiendureController # создает, без рендеринга/перенаправления. Следующее копируется из плагина проверки подлинности RESTful.
def authenticate
self.current_user = User.authenticate(params[:login], params[:password])
if logged_in?
if params[:remember_me] == "1"
current_user.remember_me unless current_user.remember_token?
cookies[:auth_token] = { :value => self.current_user.remember_token,
:expires => self.current_user.remember_token_expires_at }
end
end
end
Все, что осталось, это убедиться, что порядок фильтрации правильный.
before_filter :authenticate, :require_user, :only => :vote
N.B.: Вероятно, вы не собираетесь использовать эту версию require_user без этой версии аутентификации, поэтому имеет смысл объединить их в единый фильтр.
И все. Способ настройки обеспечивает надежный код DRY, легко используемый повторно. Размещая новые фильтры в GroupController, они доступны в любом контроллере. С этого момента добавление этой функциональности к любым другим контроллерам/действиям занимает всего 3 простых шага:
Я бы подошел к этому так, как вы описываете в нижней части вашего вопроса. Перед первым отображением страницы проверьте, зарегистрирован ли пользователь. Если да, то ссылки "Мне нравится" должны использовать свое обычное поведение. Если нет, привяжите событие клика, чтобы показать панель регистрации/входа. В этом нет ничего такого, что нельзя было бы использовать повторно. На самом деле, мы используем именно этот метод в моей работе. Любое действие пользователя, требующее аутентификации, либо следует его нормальному поведению, либо всплывает общая панель входа, в зависимости от состояния входа на момент загрузки страницы.