2016-12-08 15 views
0

私はウェルカムページにユーザーフォームを持っています。ユーザーフォームが送信されると、そのユーザーに属するWebサイトレコードとそのWebサイトに属するページレコードを作成したいと考えています。深いネストされたRailsアソシエーションを1つのフォームで作成する

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 

私のルートは

# 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 
...モデルは次のようになり

# routes.rb 

resources :users do 
    resources :websites do 
     resources :pages 
    end 
end 

...です

最後に私のユーザーコントローラ...

# 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

あなたはそれを自動的に作成したいのですか、またはユーザーはそれらのレコードの詳細をフォームに入力しますか?ネストされたフィールドを使用すると、ユーザーが詳細を入力するためです。 – Deep

+0

ちょっと、私はいくつかの問題を修正した後、質問を更新しました。私はhidden_​​fieldフィールドfields_forのデフォルトまたは生成されたコンテンツを使用しています。自動的にウェブサイトを作成することができますが、そのページにはJSでフィールドに追加するユーザー生成コンテンツがいくつかあります。 – colmtuite

+0

なぜ、コールバックを使ってウェブサイトやページを作成してみませんか? – Deep

答えて

1

コールバックは、オブジェクトのライフサイクルの特定の瞬間に呼び出されるメソッドです。コールバックを使用すると、Active Recordオブジェクトが作成、保存、更新、削除、検証、またはデータベースからロードされるたびに実行されるコードを記述することができます。あなたはuserあなたがafter_createbefore_createコールバックを使用することができます作成​​されているwebsitepageを作成する必要があるように

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 

だから、できるだけ早くお使いのユーザーはwebsitepageも作成されます作成されます。これは、データベースに存在しませんuserオブジェクト上の仮想属性を作成します

attr_accessor :page_content 

Userモデルで

:あなたが行うことができますフォームからpageためcontentを取得するために

。今すぐあなたのform

<%= f.hidden_field :page_content, class: 'js-PageContentHiddenField' %> 

このフィールドにはjavascriptの内容を追加します。今、この属性もあなたのコントローラの許可証に:

page = website.pages.build(name: 'Untitled Page', content: page_content) 

これは、必要な操作を行う必要があります。その後、

params.require(:user).permit(:email, :password, :name, :page_content) 

そして最後にこの方法では、我々はcreate_website_and_page変更の上、これに行を書きました。

まだ何らかの理由で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 

いますが、同じ formからもそれを作成しているとして、あなたは paramswebsite_idを得ることはありません。だから、あなたがしなければならないウェブサイトのパラメータとページを可能にすることができます。また、 user_idは、ネストされたフォームの場合に自動的に関連付けられるため、許可する必要はありません。

+0

助けてくれてありがとう、非常に面白い。私はafter_createコールバックを試みましたが、#<ウェブサイト>には未定義のメソッド 'build 'があります。何か案は? – colmtuite

+0

ああ、私は 'page'をビルドするのに間違いました。' page = website.pages.build'でなければなりません。私は私の答えを更新しました。 – Deep

+0

あなたは狂気だよ、ちょうど私の髪を引き出す数週間を節約した、ありがとう。最後に、ページコンテンツを何とか注入することは可能ですか?私は、divでユーザーが生成したコンテンツからページコンテンツを取得する必要があります。 – colmtuite

関連する問題