ruby-on-rails - has_one - rails model references
ValidaciĆ³n fallida La clase debe existir (5)
He tenido (horas) problemas con asociaciones en Rails. Encontré muchos problemas similares, pero no pude aplicar para mi caso:
Clase de la ciudad:
class City < ApplicationRecord
has_many :users
end
Clase del usuario:
class User < ApplicationRecord
belongs_to :city
validates :name, presence: true, length: { maximum: 80 }
validates :city_id, presence: true
end
Controlador de usuarios:
def create
Rails.logger.debug user_params.inspect
@user = User.new(user_params)
if @user.save!
flash[:success] = "Works!"
redirect_to ''/index''
else
render ''new''
end
end
def user_params
params.require(:user).permit(:name, :citys_id)
end
Vista de usuarios:
<%= form_for(:user, url: ''/user/new'') do |f| %>
<%= render ''shared/error_messages'' %>
<%= f.label :name %>
<%= f.text_field :name %>
<%= f.label :citys_id, "City" %>
<select name="city">
<% @city.all.each do |t| %>
<option value="<%= t.id %>"><%= t.city %></option>
<% end %>
</select>
end
Emigrar:
class CreateUser < ActiveRecord::Migration[5.0]
def change
create_table :user do |t|
t.string :name, limit: 80, null: false
t.belongs_to :citys, null: false
t.timestamps
end
end
Mensaje desde la consola y el navegador:
ActiveRecord::RecordInvalid (Validation failed: City must exist):
Bueno, el problema es que los atributos del modelo del Usuario que no son FK son aceptados por el método User.save, y los atributos FK como citys_id no lo son. Luego, aparece un mensaje de error en el navegador que dice "La validación falló. La ciudad debe existir".
Gracias
Pruebe lo siguiente:
belongs_to :city, optional: true
De acuerdo con los nuevos documentos :
4.1.2.11: opcional
Si establece la opción: opcional en verdadero, entonces la presencia del objeto asociado no será validada. Por defecto, esta opción está configurada en falso.
Descubrí una solución al problema "La validación falló: la clase debe existir" y es mejor que el uso:
belongs_to :city, optional: true
4.1.2.11: opcional
Si establece la opción: opcional en verdadero, entonces la presencia del objeto asociado no será validada. Por defecto, esta opción está configurada en falso.
porque aún hace una validación en el nivel de la aplicación. Resuelvo el problema haciendo mi propia validación en el método create y cambiando el método user_params:
def create
@city = City.find(params[:city_id])
Rails.logger.debug user_params.inspect
@user = User.new(user_params)
@user.city_id = @city.id
if @user.save!
flash[:success] = "Works!"
redirect_to ''/index''
else
render ''new''
end
end
def user_params
params.require(:user).permit(:name)
end
No probé este código, pero funciona en otro proyecto mío. ¡Espero que pueda ayudar a otros!
belongs_to :city, required: false
Debe agregar lo siguiente al final de la declaración de relación belongs_to:
optional: true
Es posible configurar esto en un nivel global para que funcione de la misma manera que las versiones anteriores de los rieles, pero recomendaría tomarse el tiempo para agregarlo manualmente a las relaciones que realmente lo necesitan, ya que esto causará menos dolor en el futuro.
Esto llega un poco tarde, pero esta es la forma de hacerlo por defecto en los rieles 5:
config / initializers / new_framework_defaults.rb
Rails.application.config.active_record.belongs_to_required_by_default = false
¡Espero que esto ayude!