Я думаю, что есть несколько источников ошибок здесь:
undefined method `link_to'
Это весьма необычно, поскольку link_to
является стандартным помощником вида. Вы уверены, что пространство до link_to
действительно является пространством, а не каким-то другим невидимым персонажем (иногда вы получаете их, например, на OSX, когда используете space
, удерживая alt
). Кроме того, ваш js erb должен находиться в пространстве имен ваших контроллеров, но поскольку он выполняется, когда вы выполняете действие, это, по-видимому, имеет место.
$(document).ready(function(){
Вам не нужно будет использовать это в .js.erb
шаблонов, так как нет готового события увольняют. jQuery выполняет скрипт сразу, если DOM все равно готов, поэтому он не повредит (обычно), это просто лишний.
$("#new_post").bind('ajax:success', function(xhr, data, status){
Это большая проблема. Теперь, когда вы прикрепляете обработчик, он будет прикрепляться каждый раз, когда форма будет отправлена, и сервер вернет данные. Итак, если есть ошибка, и форма будет отправлена и возвращена во второй раз, вы либо получите сообщение console
, либо вставку якоря, выполненную два раза. Так что будьте готовы к этому событию:
$("#new_post").not('.registered').addClass('registered').bind('ajax:success', function(xhr, data, status){
Это предотвратит несколько обработчиков событий.
Тогда есть третья проблема:
var user_name = data.user; // json is contained in data variable
$("#recent_posts").prepend("<%= j link_to(user_name, '#') %>");
Здесь вы пытаетесь использовать переменную, назначенную в JavaScript в erb
инлайн рубина. Это не сработает, так как рубиновая переменная user_name
оценивается серверами при визуализации шаблона. С другой стороны, назначение переменной javascript оценивается в браузере, когда клиент получает визуализированный шаблон с сервера. Так что ты можешь сделать?
link_to
не все, что магия. Он просто отображает привязную метку. Таким образом, это же можно сделать так:
var user_name = data.user; // json is contained in data variable
$("#recent_posts").prepend(["<a href='#'>", user_name, "</a>"].join(''));
Пока что так хорошо.Самая большая проблема, которую вы испытываете, заключается в следующем: сервер не может вернуть как обработанный .js.erb
шаблон , так иjson
данные сразу. Таким образом, данные, которые вы получаете в вашей функции javascript, будут только отображаемой строкой шаблона .js.erb
. Связь с сервером в JSON
действительно самое лучшее, так что давайте забудем о рельсах интегрированной обработки формы и написать его сами:
Удалить :remote => true
из вариантов формы
Добавить :format => :json
в свой create
маршрут
resources :posts, :only => [:create], :format => :json
resources :posts, :except => [:create]
Добавить JavaScript в ваших активов, который обрабатывает вашу форму удаленно
// after DOM ready
var form = $('#new_post');
form.on('submit', function(e) {
$.ajax({
url: form.prop('action'),
type: form.prop('method') || 'POST' //for create action,
data: form.serializeArray(),
dataType: form.data('type') || 'json',
success: function(data, status, xhr) {
var user_name = data.user; // json is contained in data variable
$("#recent_posts").prepend(["<a href='#'>", user_name, "</a>"].join(''));
},
error: function(xhr, status, error) {
console.log('error')
}
});
return false; //prevent normal submit
});
Теперь вы готовы вернуть чистый JSON
с сервера:
render :json => resource.to_json(:include => :errors)
Не могли бы вы включить свой 'код .js.erb' файла? – Stefan
После этого вы можете поместить код Ruby в кавычки, чтобы не разорвать ваш .prepend() –
. Каков путь к вашему файлу .js.erb? Если это не в приложении/views/_controller_name_, вы не можете быть в области с доступом к вспомогательным методам представления, например link_to. Чтобы проверить, так ли это, попробуйте явно вызвать область, заменив 'link_to' на' ActionController :: Base.helpers.link_to' – omnikron