我的欢迎页面上有一个用户表单。当用户表单被提交时,我想创建属于用户的网站记录以及属于该网站的页面记录。
我试图使用fields_for,但我不确定我做错了什么。
# welcome.html.erb
<%= form_for @user do |f| %>
<div>
<%= f.text_field :name' %>
</div>
<div>
<%= f.email_field :email %>
</div>
<div>
<%= f.password_field :password %>
</div>
<div>
<%= f.fields_for :website do |website_fields| %>
<%= website_fields.text_field :name, value: 'Untitled website' %>
<% end %>
</div>
<div>
<%= f.fields_for :page do |page_fields| %>
<%= page_fields.text_field :name, value: 'Untitled page' %>
<%= page_fields.text_field :content, class: 'js-PageContentHiddenField', value: 'Page content' %>
<% end %>
</div>
<div>
<%= f.submit 'Create account' %>
</div>
<% end %>
页面控制器看起来像这样......
# pages_controller.rb
def welcome
@user = User.new
@website = @user.websites.new
@page = @user.websites.pages.new
end
我的路线如下......
# routes.rb
resources :users do
resources :websites do
resources :pages
end
end
模型看起来像这样......
# User model
has_many :websites, :dependent => :destroy
has_many :pages, through: :websites
accepts_nested_attributes_for :websites
accepts_nested_attributes_for :pages
# Website model
belongs_to :user
has_many :pages, :dependent => :destroy
# Page model
belongs_to :website
最后我的用户控制器......
# User controller
def create
@user = User.new(shared_params)
@website = @user.websites.new(website_params)
@page = @website.pages.new(page_params)
if @user.save
auto_login(@user)
@redirect_to user_website_page_path
else
# redirect to wherever
end
end
private
def shared_params
params.require(:user).permit(:email, :password, :name)
end
def website_params
params.require(:user).permit(:name, :user_id)
end
def page_params
params.require(:user).permit(:name, :website_id)
end
我现在遇到的问题是用户名被保存为页面和网站名称等。我认为我的参数存在一些问题。另外,我不确定如何设置重定向以在创建页面后重定向到该页面。
几个星期以来,我一直在玩各种配置,我无法解决这个问题。我无法强调我很少知道我在这里做什么,真的很喜欢一些帮助!答案 0 :(得分:1)
回调是在对象生命周期的某些时刻被调用的方法。通过回调,可以编写将在数据库中创建,保存,更新,删除,验证或加载Active Record对象时运行的代码。
因此,在创建website
时需要创建page
和user
,您可以使用after_create
或before_create
回调。创建对象后执行after_create
,并在创建对象之前执行before_create
回调。
因此,在您的User
模型中,您可以做的是:
after_create :create_website_and_page
def create_website_and_page
website = websites.build(name: 'Untitled Website')
page = website.pages.build(name: 'Untitled Page', content: 'Page Content')
website.save # This will automatically save the associated page too
end
创建用户后,website
和page
也会被创建。
要从您可以执行的表单中获取content
的{{1}}:
在page
模型中:
User
这将在attr_accessor :page_content
对象上创建一个虚拟属性,该属性在数据库中不存在。现在在user
:
form
因此,请在此字段中附加javascript中的内容。现在在你的控制器中也允许这个属性:
<%= f.hidden_field :page_content, class: 'js-PageContentHiddenField' %>
然后最后在我们上面写的方法params.require(:user).permit(:email, :password, :name, :page_content)
中将行更改为:
create_website_and_page
这应该是必需的。
如果您仍然希望出于任何原因使用page = website.pages.build(name: 'Untitled Page', content: page_content)
,那么您所犯的错误就是nested_form
。只需在创建操作的顶部放置params
,然后查看debugger
即可。因此,要允许您必须执行的网站和页面参数:
params
但是你永远不会在def user_params
params.require(:user).permit(:email, :password, :name, website_attributes: [:name], page_attributes: [:name, :website_id, :content])
end
中获得website_id
,因为你也是从同一个params
创建的。而且form
也不需要被允许,因为在嵌套表单的情况下它会自动关联。