ruby on rails - relacion - Rails: la actualización de los atributos anidados no funciona para la relación de uno a varios
relacion uno a muchos rails (6)
Estoy tratando de implementar los atributos anidados y la creación de un horario está funcionando. Pero falla al editar sin dar ningún error. Funciona con una relación de uno a uno , pero no para uno a muchos . Estoy pasando el id del cronograma como se indica en este documento: NestedAttributes
Tengo estos modelos:
class Article < ActiveRecord::Base
has_many :schedules
accepts_nested_attributes_for :schedules
end
class Schedule < ActiveRecord::Base
belongs_to :article
end
y aquí hay un fragmento del controlador para los parámetros fuertes de la lista blanca:
def article_params
params.require(:article).permit(schedules_attributes: [ :id, :schedule_for, :content, :time_zone, :date, :time ])
end
Y aquí hay una muestra que probé a través de la consola Rails :
article_params = {"schedules_attributes"=>{"0"=>{"schedule_for"=>"pre", "content"=>"This is a scheduled message for ETS - !!!!!!!", "time_zone"=>"American Samoa", "date"=>"2013-10-20", "time"=>"11:15 AM", "id"=>"1"}}}
article = Article.find(1)
article.update(article_params)
D, [2013-10-25T16:42:50.266517 #2296] DEBUG -- : (0.1ms) BEGIN
D, [2013-10-25T16:42:50.267789 #2296] DEBUG -- : Schedule Load (0.3ms) SELECT "schedules".* FROM "schedules" WHERE "schedules"."article_id" = $1 AND "schedules"."id" IN (1) [["article_id", 1]]
D, [2013-10-25T16:42:50.273288 #2296] DEBUG -- : (0.3ms) COMMIT
Seleccionó el programa correcto pero no realizó una consulta de actualización y no tuvo ningún error. ¿Me estoy perdiendo de algo?
EDITAR:
Estoy usando Ruby 2.0 y Rails 4.
Aquí hay algunas ideas para ti:
def article_params
schedules_attributes: [ :id, :schedule_for, :content, :time_zone, :date, :time ]
end
Debiera ser:
def article_params
params.require(:article).permit(schedules_attributes: [ :id, :schedule_for, :content, :time_zone, :date, :time ])
end
Creo que el problema aquí tiene que ver con cómo lo estás probando. Si observa la documentación ( http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html ) en "One-to-many" verá el siguiente ejemplo de cómo usar la asociación anidada para la objeción creación:
params = { member: {
name: ''joe'', posts_attributes: [
{ title: ''Kari, the awesome Ruby documentation browser!'' },
{ title: ''The egalitarian assumption of the modern citizen'' },
{ title: '''', _destroy: ''1'' } # this will be ignored
]
}}
member = Member.create(params[:member])
El ejemplo que ha publicado no pasa los schedules_attributes
como una Array
, sino como un Hash
, que no parece ser el uso correcto. Aunque este ejemplo es para ActiveRecord::Base.create
, lo mismo debe aplicarse a ActiveRecord::Base#update_attributes
.
El problema aquí parece que no está utilizando parámetros accepts_nested_attributes_for
y accepts_nested_attributes_for
correctamente.
Puedes intentar
modelo
accepts_nested_attributes_for :schedules
archivo controlador
def article_params
params.require(:article).permit(:my, :attributes, :schedules: [:schedule, :whitelist])
end
@article.update_attributes!(article_params)
Para mí es estúpido que los rieles requieran ambos parámetros fuertes y accepts_nested_attributes_for
para que funcionen de esta manera, pero tal vez me falta algo.
¡También intenta usar .update_attributes!
con a !
, esto le dirá a los rieles que generen errores, para que sepa qué está pasando.
Tienes article[schedules_attributes][0][schedule_for]
en tu para, no soy 100% positivo en esto, pero creo que esto se enviará como params [: artículo] [: schedule_attributes_0] [schedule_for]
¿Puedes intentar poner article[schedule_attributes][][attribute_name]
Por favor, mira la opción inverse_of
en la documentación, que está vinculada a tu pregunta
Úselo en los modelos:
class Article < ActiveRecord::Base
has_many :schedules, inverse_of: :article
accepts_nested_attributes_for :schedules
end
class Schedule < ActiveRecord::Base
belongs_to :article, inverse_of: :schedules
end
Prueba esto:
Consola Rails
a = Article.find(1)
b = a.schedules.first
article_params = {"schedules_attributes"=>{"0"=>{"schedule_for"=>"pre", "content"=>"This is a scheduled message for ETS - !!!!!!!", "time_zone"=>"American Samoa", "date"=>"2013-10-20", "time"=>"11:15 AM", "id"=>"1"}}}
b.update(article_params)
b.save
También es posible que desee editar params de artículos solo para que sea un objeto fácil.
remita este PRO railscasts para la asociación anidada ... es un gran episodio de RAILSCASTS PRO para la asociación anidada