Вместо создания записи find_or_create_by просто возвращает nil. И я не знаю почему.
Я делаю это:
current_store.jet.find_or_create_by(seller_id: seller_id) do |credentials|
credentials.update_attributes(
marketplace: marketplace,
seller_id: seller_id,
auth_token: auth_token)
end
И он возвращает это вместо того, чтобы по какой-то причине создавать запись:
*** NoMethodError Exception: undefined method `find_or_create_by' for nil:NilClass
Я проверил все аргументы, и они верны. Но конечно экземпляра jet пока нет, но в этом суть.
Моя таблица Jet выглядит так:
create_table "jets", force: :cascade do |t|
t.text "auth_token"
t.text "marketplace"
t.integer "store_id"
t.boolean "three_speed"
t.text "seller_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
И мой метод current_store выглядит так и возвращает правильное хранилище.
def current_store
@current_store ||= Store.find(session[:fba_shipping_id])
end
Где я заблудился?
Обновлено: Вот еще немного информации об отношениях ..
class Store < ActiveRecord::Base
has_one :jet
end
А также
class Jet < ActiveRecord::Base
belongs_to :store
end
@HeliosdeGuerra хорошая идея, и я обновил OP, но Storehas_oneJet и Jetbelongs_toStore
Ах, на has_one синтаксис немного другой. Вы должны использовать метод build_other. Попробуйте current_store.build_jet.find_or_create_by ...
Стреляйте .., который вернул NoMethodError (undefined method find_or_create_by 'для # <Jet: 0x007f4a6ca87808>): `
когда я сделал этот current_store.build_jet.find_or_create_by(seller_id: seller_id)





Поскольку у вас есть ассоциация has_one, вероятно, было бы проще написать метод следующим образом:
Jet.find_or_create_by(store_id: current_store.id) do |jet|
jet.seller_id = seller_id
jet.marketplace = marketplace
jet.auth_token = auth_token
end
Мне кажется, это позволило бы достичь того, что вы хотите сделать, но более стандартным способом.
Имейте в виду, что при этом не будут обновлены атрибуты (seller_id, marketplace, auth_token) существующего jet, но будет создан атрибут с этими атрибутами, если для current_store еще не назначен jet.
Вы хотите обновить эти атрибуты, даже если запись уже существует?
Ваша текущая проблема в том, что
current_store.jet
возвращает nil, таким образом, NoMethodError.
Если в магазине есть только 1 Jet, то в Store также может быть только 1 Seller из этого 1 Jet.
has_one (Документация) предлагает методы компоновщика build_association и create_association, так что вы можете использовать
current_store.create_jet(marketplace: marketplace,
seller_id: seller_id,
auth_token: auth_token)
Однако вы можете убедиться, что на Store еще нет Jet, например
@jet = current_store.jet || current_store.create_jet(marketplace: marketplace,
seller_id: seller_id,
auth_token: auth_token)
Это не обновит существующий Jet, если это было вашим намерением, как указано @HeliosdeGuerra в комментариях. Если вы действительно хотели использовать эти методы и обновить существующий Jet, вы могли бы пойти с чем-нибудь тупым, например:
@jet = current_store.jet || current_store.create_jet(seller_id: seller_id)
@jet.update_attributes(marketplace: marketplace,auth_token: auth_token)
Однако в обоих случаях вы должны убедиться, что Jet прошел проверку, например.
# Example 1
@jet = current_store.jet || current_store.create_jet(marketplace: marketplace,
seller_id: seller_id,
auth_token: auth_token)
if @jet.persisted?
# passed validation or already existed
else
# failed validation
end
# Example 2
@jet = current_store.jet || current_store.create_jet(seller_id: seller_id)
if @jet.update_attributes(marketplace: marketplace,auth_token: auth_token)
# passed validation
else
# failed validation
end
Чтобы было ясно, это не приведет к обновлению атрибутов существующего jet ... Неясно, хочет ли @ToddT обновить эти атрибуты, если самолет уже существует или нет. Судя по полям, кажется, что он, вероятно, не захочет обновлять эти поля, но то, как он изначально написал метод, я предполагал, что он действительно хотел обновить поля.
@HeliosdeGuerra обновлен, и, честно говоря, я бы использовал ваше решение, за исключением того факта, что я не уверен, что произошло бы, если бы store_id существовал, а seller_id не существовал, поскольку это создало бы 2 Jet для 1 Store. Я предполагаю, что это лишит недавно созданный Jet из-за ограничения 1 на запрос для has_one
Ах, хороший момент ... Я обновлю свой ответ, чтобы лучше учесть эту ситуацию, в качестве альтернативы хорошим решениям, которые вы предоставляете ...
Трудно сказать, не видя определения ассоциации между
StoreиJet, но еслиStorehas_many :jets, то разве вы не должны иметь множественное числоjetsв вашем утверждении? (например,current_store.jets.find_or_create_by)