Entonces, estoy usando una API para obtener información sobre el clima, se ejecuta todos los días, lo que estoy tratando de hacer es actualizarme si ya existe, y crear una nueva si no está en la tabla. Quiero actualizar todos los atributos al actualizar. lo intenté
model = Model.where(column_name: value).first_or_initialize(locked: false)pero me sale un error diciendo:
atributo desconocido bloqueado para el modelo
aumentar UnknownAttributeError.new(self,k.to_s)
Si necesita algo, pregunte y lo comentaré o editaré. Soy nuevo en Ruby y Rails.
En primer lugar, consulte los documentos aquí . Una tabla con el nombre de tiempo con los siguientes atributos location: string temperature:integer wind:string que debe actualizarse o inicializarse en función de la ubicación funcionaría así
@weather_record = Weather.find_or_initialize_by(location: location_value) @weather.temperature = -60 @weather.wind = strong @weather.saveA continuación, nunca, nunca use un nombre reservado para un modelo, así que no tenga Modelo como el nombre de su tabla.
Por último en tu ejemplo
model.Model.where(column_name: value).first_or_initialize(locked: false) está diciendo a_record.ClassName.where , lo cual es simplemente incorrecto. Si está utilizando un método de clase, comience con el nombre de la clase, por ejemplo, Weather.where , si está utilizando métodos de instancia, use el nombre de la instancia, por ejemplo an_instance_of_weather.some_field
En primer lugar, la parte model.Model debe ser solo Model , ya que Model es su clase.
Se supone que locked es una columna/atributo de la clase Modelo, aunque parece que no es el caso a juzgar por su error. Por lo tanto, other_column_name como ejemplo.
Explicación de lo que está haciendo:
Model.where(column_name: value).first_or_initialize(other_column_name: some_value) Model.where(column_name: value) : obtiene modelos que satisfacen la condición column_name == value
first_or_initialize : si se encontró un modelo tal que column_name == value, se devuelve ese. De lo contrario, inicializa un modelo con column_name = valor.
Al pasar other_column_name: some_value , si el modelo no se encontró y debe inicializarse, establece other_column_name en some_value pero: 1) no lo actualiza si se encontró inicialmente y 2) no guarda el registro.
El equivalente de first_or_initialize que guarda el nuevo registro sería first_or_create pero esto aún no actualizaría el registro si ya existiera.
Entonces, deberías hacer algo como esto:
m = Model.where(column_name: value).first_or_initialize m.other_column_name = some_value m.save De esta manera, primero obtiene un modelo donde column_name es value o inicializa uno nuevo con este valor si aún no existe. Luego, establece el atributo other_column_name en some_value y guarda el modelo.
Una alternativa de una sola línea sería
Model.where(column_name: value).first_or_create.update(other_column_name: some_value)Sin embargo, tenga en cuenta que si necesita ser creado, este realizará 2 consultas (la inserción y la actualización).
Sobre la parte del error. Dice que el atributo bloqueado no existe en el registro del Modelo. ¿Son estas clases las que creaste? ¿Está utilizando algún proyecto preexistente? Podría intentar publicar Model.attribute_names y tal vez su schema.rb
Prueba esto compañero:
column_name_value = (Way that you get the info from data) model = Model.find_or_initialize_by column_name: column_name_value¡Avísame si funcionó!