2016-12-21 11 views
0

Я использую Rails 5 и PostGres 9.5. У меня есть модель со следующим полем ...Как создать или обмануть модель на основе одного из ее атрибутов? (Rails 5)

title    | character varying   | 

Я хотел бы, чтобы либо создать или обновить модель в моем дб/файл семян на основе его название, которое является уникальным ограничением. Поэтому я пробовал

scenario = Scenario.find_or_initialize_by_title(s.title) 
scenario.update_attributes(Hash[*@record.attributes.except('created_at','updated_at','id').map { |a| [a.first, nil] }.flatten]) 

, но я получил следующую ошибку. Каков правильный способ создания или обновления моей модели, а также исключить перечисленные атрибуты?

localhost:sims nataliab$ rake db:seed 
rake aborted! 
NoMethodError: undefined method `find_or_initialize_by_title' for #<Class:0x007fb22d28f820> 
Did you mean? find_or_initialize_by 
/Users/nataliab/.rvm/gems/ruby-2.3.0/gems/activerecord-5.0.0.1/lib/active_record/dynamic_matchers.rb:21:in `method_missing' 
/Users/nataliab/Documents/workspace/sims/db/seed/scenarios.rb:165:in `block in <top (required)>' 
/Users/nataliab/Documents/workspace/sims/db/seed/scenarios.rb:164:in `each' 
/Users/nataliab/Documents/workspace/sims/db/seed/scenarios.rb:164:in `<top (required)>' 
/Users/nataliab/.rvm/gems/ruby-2.3.0/gems/activesupport-5.0.0.1/lib/active_support/dependencies.rb:293:in `require' 
/Users/nataliab/.rvm/gems/ruby-2.3.0/gems/activesupport-5.0.0.1/lib/active_support/dependencies.rb:293:in `block in require' 
/Users/nataliab/.rvm/gems/ruby-2.3.0/gems/activesupport-5.0.0.1/lib/active_support/dependencies.rb:259:in `load_dependency' 
/Users/nataliab/.rvm/gems/ruby-2.3.0/gems/activesupport-5.0.0.1/lib/active_support/dependencies.rb:293:in `require' 
/Users/nataliab/Documents/workspace/sims/db/seeds.rb:10:in `<top (required)>' 
/Users/nataliab/.rvm/gems/ruby-2.3.0/gems/activesupport-5.0.0.1/lib/active_support/dependencies.rb:287:in `load' 
/Users/nataliab/.rvm/gems/ruby-2.3.0/gems/activesupport-5.0.0.1/lib/active_support/dependencies.rb:287:in `block in load' 
/Users/nataliab/.rvm/gems/ruby-2.3.0/gems/activesupport-5.0.0.1/lib/active_support/dependencies.rb:259:in `load_dependency' 
/Users/nataliab/.rvm/gems/ruby-2.3.0/gems/activesupport-5.0.0.1/lib/active_support/dependencies.rb:287:in `load' 
/Users/nataliab/.rvm/gems/ruby-2.3.0/gems/railties-5.0.0.1/lib/rails/engine.rb:549:in `load_seed' 
/Users/nataliab/.rvm/gems/ruby-2.3.0/gems/activerecord-5.0.0.1/lib/active_record/tasks/database_tasks.rb:268:in `load_seed' 
/Users/nataliab/.rvm/gems/ruby-2.3.0/gems/activerecord-5.0.0.1/lib/active_record/railties/databases.rake:196:in `block (2 levels) in <top (required)>' 
/Users/nataliab/.rvm/gems/ruby-2.3.0/gems/rake-11.3.0/exe/rake:27:in `<top (required)>' 
/Users/nataliab/.rvm/gems/ruby-2.3.0/bin/ruby_executable_hooks:15:in `eval' 
/Users/nataliab/.rvm/gems/ruby-2.3.0/bin/ruby_executable_hooks:15:in `<main>' 
Tasks: TOP => db:seed 
(See full trace by running task with --trace) 
+0

Try: 'Scenario.find_or_initialize_by (название: Подзаг)' –

ответ

0

Попробуйте Scenario.find_or_initialize_by(title: s.title)

+0

Это на самом деле должно быть предусмотрено ответ на вопрос - он непосредственно решает проблему, как указано. К сожалению, под этой ошибкой, похоже, другая, отдельная ошибка. –

1

Сообщение об ошибке дает подсказку:

NoMethodError: undefined method `find_or_initialize_by_title' for #<Class:0x007fb22d28f820> 
Did you mean? find_or_initialize_by 

динамические имена методов теперь на самом деле не "Rails утвержденных" вы должны использовать find_or_initialize_by. В этом случае вы будете использовать:

Scenario.find_or_initialize_by(title: s.title) 

Вот ссылка на апи документ по этому методу: http://apidock.com/rails/v4.0.2/ActiveRecord/Relation/find_or_initialize_by

+0

Спасибо, но если нет названия и с помощью вашего кода, следующая строка дает атрибут «NoMethodError: undefined method» для ошибки nil: NilClass. Моя цель - создать объект, если название не существует, или обновить атрибуты существующей модели, если она существует. –

+0

Эта цель - именно то, что будет делать этот код. Что вы имеете в виду, что нет названия? почему он говорит, что сценарий равен нулю? есть ли у вас модель под названием «Сценарий»? у него есть столбец в db, называемый 'title'? если нет, то да, этот код не сработает. –

+0

Посмотрите на api doc для 'find_or_initialize_by' - он также охватывает такие вещи, как, как передать в блок, который дает все другие значения поля. Также рассмотрите 'find_or_create_by (title: s.title)' –