[英]How to save to Database with associations in rails protecting mass assignment
尝试了几个小时后,我无法保存到数据库。
上下文是这样的:我有两种类型的用户,一种只需要非常基本的信息(用户名,电子邮件,密码),另一种需要很多信息的用户(年龄,性别,城市等) ]
由于表中将存在大量的Null值,因此我没有使用STI。 因此,我创建了这三种模式,在这种模式下,用户是否拥有个人资料(个人资料表)取决于其类型[1或2],并且此个人资料的字段是该用户所居住的城市,与该城市中的另一个表相关DB,城市表
class User < ActiveRecord::Base
has_one :profile
has_one :city, through: :profile
end
class Profile < ActiveRecord::Base
belongs_to :user
belongs_to :city
[...a bunch of fields here]
end
class City < ActiveRecord::Base
has_many :profiles
has_many :users, through: :profiles
end
当我在rails console中与他们一起玩时,一切正常:
usr = User.new(name: "roxy", email: "roxy@example.me", password: "roxanna", password_confirmation: "roxanna", utype: 1)
cty = City.new(name: "Bucaramanga")
prf = Profile.new (rname: "Rosa Juliana Diaz del Castillo"...)
prf.city = cty
usr.profile = prf
usr.valid?
=> true
usr.save
=> true
但是当我尝试保存在应用程序中时(查看模型)
<%= f.label :city, "En que ciudad te encuentras?"%>
<%= select_tag :city, options_from_collection_for_select(City.all, 'id', "name"),{:prompt => 'Selecciona tu ciudad'}%>
def new
@profile = Profile.new
end
def create
@profile = params[:profile]
@city= City.find_by_id(params[:city].to_i)
@profile.city = @city
end
我收到此错误:
undefined method `city=' for #<ActiveSupport::HashWithIndifferentAccess:0xa556fe0>
有人可以帮帮我吗?
更新正如David所建议的那样,我在create方法的第一行中创建了Profile对象,因此我的控制器现在如下所示:
def create
@profile = Profile.new(params[:profile])
@city= City.find_by_id(params[:city].to_i)
@profile.city = @city
@usr = current_user
if @usr.profile.exists? @profile
@usr.errors.add(:profile, "is already assigned to this user") # or something to that effect
render :new
else
@usr.profile << @profile
redirect_to root_path
end
end
但是我现在收到这个错误
undefined method `exists?' for nil:NilClass
current_user返回@current_user
def current_user
@current_user ||= User.find_by_remember_token(cookies[:remember_token])
end
你能告诉我,我做错了什么吗?
我想写这篇给所有刚开始的我,并坚持这一步。
我必须创建一个新项目并对其进行操作以意识到我做错了什么。 我发现我正在验证我添加到“ Profiles
表中并具有
# education :string(255) not null
但我尚未将其添加到表单中,因此启动的错误是:
Failed to save the new associated so_profile.
现在,您知道如果遇到此错误,请检查您的架构并查找表单中可能缺少的NOT_NULL字段,还可以注释掉所有模型验证,并在取消注释后确定它们是否起作用。
因此,我的最终模型:
class User < ActiveRecord::Base
has_one :profile
has_one :city, through: :profile
attr_accessible :email, :name
end
class Profile < ActiveRecord::Base
belongs_to :user
belongs_to :city
attr_accessible :age, :fcolor, :gender
end
class City < ActiveRecord::Base
has_many :profiles
has_many :users, through: :profiles
attr_accessible :name
end
我的控制器:
class ProfilesController < ApplicationController
def new
@user = User.find_by_id(params[:id])
@profile = Profile.new
end
def create
@profile = Profile.new(params[:profile])
city = City.find_by_id(params[:city])
@profile.city = city
@user = User.find_by_id(params[:userid])
@user.profile = @profile
if @user.save
flash[:success] = "Guardado"
redirect_to profile_path(id: @user.id)
end
end
def show
@user = User.find(params[:id])
end
end
class UsersController < ApplicationController
def new
@user = User.new
end
def create
@user = User.new(params[:user])
if @user.save
flash[:success] = "Registrado!"
redirect_to new_profile_path(id: @user.id)
else
flash[:error] = "No Registrado :("
redirect_to new
end
end
def show
@user = User.find_by_id(params[:id])
end
end
在真实的应用程序中,您必须使用Cookies或其他方式使会话保持活动状态,并因此使用从您获得user_id的位置来的user_token,但是它可以与关联一起使用。
观点:
profile / new.html.erb
<%= @user.name %>
<%= form_for @profile, url: {action: :create, userid: @user.id } do |f| %>
<%= f.label :age, "Edad" %>
<%= f.text_field :age%> <br />
<%= label :city, "Ciudad"%>
<%= select_tag :city, options_from_collection_for_select(City.all, 'id', 'name')%>
<%= f.submit %>
<% end %>
profile / show.html.erb
Hello <%= @user.name %><br />
Tu edad es: <%= @user.profile.age %><br />
Vives en <%= @user.profile.city.name%>
users / new.html.erb
<%= form_for @user do |f|%>
<%= f.label :name, "Nombre"%>
<%= f.text_field :name, size: 20, placeholder: "Escribe tu nombre aqui" %><br />
<%= f.label :email, "Email"%>
<%= f.text_field :email, size: 20, placeholder: "Escribe tu email aqui" %><br />
<%= f.submit "Sign me up!"%>
users / show.html.erb
Name: <%= @user.name %><br />
Email: <%= @user.email %>
就是这样!
干杯。
我认为正确的是
@so_profile.City
不
@so_profile.city
因为班级名称是City
学习阅读错误消息。 问题在于@profile是一个散列,因为您实际上并未在create
方法的第一行上创建新的Profile对象。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.