#json #ruby-on-rails-3
#json #ruby-on-rails-3
Вопрос:
У меня странная проблема с методом to_json в моем приложении Rails 3. (ну, по крайней мере, я думаю, что это связано с to_json)
В моем контроллере я получаю список всех библиотек, хранящихся в базе данных
@libraries = Library.where( "latitude IS NOT NULL AND longitude IS NOT NULL" )
И затем я создаю файл json, который содержит информацию о библиотеке выше.
my_file = File.new("public/javascripts/libraries.json", "w")
my_file.write "var libs = {'libraries' : "
my_file.write @libraries.to_json( :only => [ :id, :name, :address, :latitude, :longitude ])
my_file.write "};"
Затем, на мой взгляд, я отображаю каждый объект библиотеки на карте Google. В файле view я считываю файл json, загружая библиотеки.файл json в виде файла javascript.
Теперь проблема в том, что объекты библиотеки отображаются на карте Google ИНОГДА, но не постоянно, и с помощью Firebug я смог определить, что иногда переменная «libs», которая содержится в файле JSON, «не определена».
Это заставляет меня думать, что файл не был полностью записан, или данные в файле были загружены не полностью. Но я не слишком уверен, что это такое.
У кого-нибудь есть идея, что может быть причиной этого?
Ответ №1:
Я не совсем уверен, в чем проблема, но я думаю, что это связано с файлом, который вы создаете.
Я бы посоветовал вам сделать это simply return the json data to the view
, а затем вы можете обработать это на стороне клиента, используя javascript или jquery или любой другой фреймворк.
Таким образом, вы также можете убедиться в правильности данных, просмотрев их в Firebug.
или
Вместо того, чтобы делать это файлом, просто hold the json data in a variable
и затем вы можете получить доступ к переменной в представлении.
Зачем утруждать себя созданием файла, когда вы можете сделать это без него.
Причины:
- Создание файла — это процесс ввода-вывода, и это увеличило бы стоимость.
- Каждый раз, когда вы извлекаете данные из представления, вы будете выполнять вызов выборки, снова вызов ввода-вывода. Вы можете сделать то же самое, просто поместив это в переменную, таким образом, все это будет там, в памяти.
Я говорю это потому, что каждый раз вы создаете новый файл, а файлы, которые вы создали до текущего http-вызова, исчезают и бесполезны.
Ответ №2:
Да, вероятно, это вызвано тем фактом, что вы записываете его в файл вместо того, чтобы просто включить его в тег. Потому что, вероятно, случается (иногда), что сервер получает запрос, записывает файл json, затем отображает представление и отправляет это представление клиенту. Затем клиенту предлагается загрузить библиотеки.файл json приводит к другому запросу к серверу для извлечения этого файла. Но что, если этот файл в этот самый момент переписывается, потому что другой клиент отправил запрос в то же время? Произойдет сбой.
Есть несколько других способов, которыми вы могли бы это сделать. Первый и, вероятно, самый быстрый способ запуска — включить это в свой контроллер и просмотреть вместо записи в файл:
#controller
@libraries = Library.where( "latitude IS NOT NULL AND longitude IS NOT NULL" ).to_json( :only => [ :id, :name, :address, :latitude, :longitude ])
#view
<script type="text/javascript">
var libs = {'libraries': <%= @libraries.html_safe %>}
</script>
Но лучшим решением, вероятно, было бы запланировать какое-либо задание для загрузки библиотеки из базы данных через определенные промежутки времени и записи в файл json, возможно, раз в день, потому что я думаю, что на самом деле нет необходимости загружать их из базы данных постоянно, если они не меняются от одной минуты к следующей.