2015-08-15 12 views
-1

Работы в разработке, но не в производстве. Когда я подчиняюсь привычке. Все дни проверяются:ОШИБКА: значение массива должно начинаться с "{"

enter image description here

И когда я представляю в журналах Heroku показать:

2015-08-15T03:37:10.067022+00:00 app[web.1]: Processing by HabitsController#create as HTML 
2015-08-15T03:37:10.067084+00:00 app[web.1]: Parameters: {"utf8"=>"✓", "authenticity_token"=>"n+tS6pcb6WUHTCdV9BZqp/nFefhbPKAE+UTUouu2x1qK0pNulK+XNT4z8AhDuwEfZ1Z860fqnqQ/YXlARyplbQ==", "habit"=>{"committed"=>["sun", "mon", "tue", "wed", "thu", "fri", "sat", ""], "date_started(2i)"=>"8", "date_started(3i)"=>"14", "date_started(1i)"=>"2015", "trigger"=>"", "action"=>"test", "target"=>"", "reward"=>"", "tag_list"=>"", "conceal"=>"0"}, "button"=>""} 

Но тогда я получаю подтверждение ошибки флэш-сообщение, потому что :committed дней присутствие не выходит правда даже если они все проверяются.

При дальнейшем расследовании, я понимаю, что я не могу mark_completed любой из привычек производства, которые я думаю, что это связано с вышеуказанной проблемы:

2015-08-15T03:34:24.227822+00:00 heroku[router]: at=info method=POST path="/habits/sort" host=www.personalcontrolcenter.com request_id=ef56c920-dee8-4797-967b-34354ff83fbc fwd="75.90.62.187" dyno=web.1 connect=0ms service=197ms status=500 bytes=274 
2015-08-15T03:34:29.713874+00:00 app[web.1]: Started PUT "/mark_completed/7" for 75.90.62.187 at 2015-08-14 23:34:29 -0400 
2015-08-15T03:34:29.720020+00:00 app[web.1]: Processing by HabitsController#mark_completed as JS 
2015-08-15T03:34:29.720027+00:00 app[web.1]: Parameters: {"id"=>"7"} 
2015-08-15T03:34:29.924799+00:00 app[web.1]: PG::InvalidTextRepresentation: ERROR: array value must start with "{" or dimension information 
2015-08-15T03:34:29.924804+00:00 app[web.1]: : UPDATE "habits" SET "committed" = $1, "completed_at" = $2, "updated_at" = $3 WHERE "habits"."id" = $4 
2015-08-15T03:34:29.924807+00:00 app[web.1]: Completed 500 Internal Server Error in 204ms 
2015-08-15T03:34:29.926694+00:00 app[web.1]: 
2015-08-15T03:34:29.926697+00:00 app[web.1]: ActiveRecord::StatementInvalid (PG::InvalidTextRepresentation: ERROR: array value must start with "{" or dimension information 
2015-08-15T03:34:29.926698+00:00 app[web.1]: : UPDATE "habits" SET "committed" = $1, "completed_at" = $2, "updated_at" = $3 WHERE "habits"."id" = $4): 
2015-08-15T03:34:29.926700+00:00 app[web.1]: app/controllers/habits_controller.rb:32:in `mark_completed' 

Так что я думаю, что нам нужно просто переписать habit_params где У меня есть :committed => []. Я пробовал это без скобок.

habits_controller.rb

def create 
    if current_user == nil 
     # If there is no user, store the goal values to the session. 
     session[:habit_date_started] = [params["habit"]["date_started(3i)"], params["habit"]["date_started(2i)"], params["habit"]["date_started(1i)"]].join('/') 
     session[:habit_committed] = params["habit"]["committed"].reject(&:empty?) 
     session[:habit_action] = habit_params[:action] 
     session[:habit_target] = habit_params[:target] 
     session[:habit_reward] = habit_params[:reward] 
     session[:habit_order] = habit_params[:order] 
     session[:habit_missed_days] = habit_params[:missed_days] 
     redirect_to valuation_signup_url 
    else 
     @habit = current_user.habits.build(habit_params) 
     if @habit.conceal == true 
     @habit.save_with_current_level 
     redirect_to @habit, notice: 'Habit was secretly created. Remember, 3 strikes and your level restarts. Good luck!' 
     elsif 
     @habit.save_with_current_level 
     track_activity @habit 
     redirect_to @habit, notice: 'Habit was successfully created. Remember, 3 strikes and your level restarts. Good luck!' 
     else 
     flash.now[:danger] = 'Required Fields: "Committed to", "Started", and "Enter Habit"' 
     render 'new' 
     end 
    end 
    end 

    def habit_params 
    params.require(:habit).permit(
     :committed => [], # In development if I comment this line out it still passes 
    end 
end 

habit.rb

validates :committed, presence: true 
serialize :committed, Array 

def save_with_current_level 
    self.levels.build 
    self.levels.build 
    self.levels.build 
    self.levels.build 
    self.levels.build 
    self.save 
end 

развитие дб

t.text  "committed", default: "---\n- sun\n- mon\n- tue\n- wed\n- thu\n- fri\n- sat\n" 

производство дб

committed | text[]      | default '{sun,mon,tue,wed,thu,fri,sat}'::text[] 

_form

<%= f.collection_check_boxes :committed, Date::ABBR_DAYNAMES, :downcase, :to_s %> 

ответ

2

PostgreSQL поддерживает arrays columns natively, следовательно text[] и массив по умолчанию в базе данных производства:

committed | text[] | default '{sun,mon,tue,wed,thu,fri,sat}'::text[] 
       ^^   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^  

ActiveRecord в Rails4 поддерживает PostgreSQL массивы нативно так что вам не нужно ничего особенно в вашей модели. В частности, вам не нужно это:

serialize :committed, Array 

Это будет пытаться конвертировать committed массивы YAML прежде, чем AR пытается поместить их в базу данных. Оглянитесь на значение по умолчанию для столбца committed:

'{sun,mon,tue,wed,thu,fri,sat}'::text[] 

{...} нотация текстовое представление массива PostgreSQL. Имея serialize committed в вашей модели, вы пытаетесь поместить строку YAML в столбец массива PostgreSQL, YAML не будет выглядеть как '{...}', поэтому это не будет допустимым текстовым представлением массива; следовательно, ошибка, жалующаяся на отсутствие {.

Первое, что вам нужно сделать, чтобы решить эту проблему, чтобы удалить это:

serialize :committed, Array 

от модели.

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

"---\n- sun\n- mon\n- tue\n- wed\n- thu\n- fri\n- sat\n" 

Это YAML представление массива и предполагает, что вы используете SQLite в развитие. Если это так, то вы должны установить PostgreSQL локально, чтобы вы могли разрабатывать, тестировать и развертывать в одной базе данных.

+0

Если вы используете PostgreSQL в разработке, то это хорошо, но вы каким-то образом столкнулись с разными типами столбцов для 'commit' в разработке и производстве. Ваша база данных разработки настроена на использование 'serialize', но ваша производственная база данных настроена на использование столбца массива. –

+0

Вам нужно решить, хотите ли вы использовать массив или «сериализовать», а затем исправить другую базу данных так, чтобы совпадало как производство, так и разработка. Это 'NoMethodError', вероятно, из' commit.include? 'something'', когда 'commit.nil?', вы можете сказать 'commit.to_a.include?', если вы хотите рассматривать 'nil' как пустые массивы. У вас есть существующие данные с NULL в 'habits.committed'? –

+0

Спасибо за ваш хорошо продуманный ответ:] Итак, я удалил «нулевые» вручную. Затем я переключил миграцию на 'add_column: habits,: commit,: text, default: Date :: ABBR_DAYNAMES.map (&: downcase), array: true'. К сожалению, установив это для производства, у меня будет небольшая проблема в разработке, но я не забочусь о ее единственном производстве, которое имеет значение. Может быть, когда-нибудь я открою тайну того, почему в этом случае они действуют по-другому:] –

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