Rails 5.1.2 Wicked Gem and Nested Attributes

731 Views Asked by At

Ruby: 2.4.0
Rails: 5.1.2


Hey Guys, I'm not completely new to Rails but definitely not an expert.

What I'm trying to do is to create a wicked wizard with nested attributes.

I already searched via Google, GitHub and StackOverflow but haven't found anything except of this and that.

Both is not working.

What I have is the following:

-_-_-_-_-_-_-_-_-_-_-_-_-_ EDIT !!!-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_

The problem was, that i havent defined an create action -.-' i had to modify some variable names as well. rails is a bit confusing with the pluralization sometimes in my opinion. luckily was was finally able to do this super simple stuff :D


Models

user.rb (from the devise gem)

 class User < ApplicationRecord

    has_one :accountinfo
    accepts_nested_attributes_for :accountinfo, update_only: true

    devise :database_authenticatable, :registerable,
           :recoverable, :rememberable, :trackable, :validatable

    validates_presence_of :password, :email, :accounttype

end

account_information.rb

edit: accountinfo.rb

The model i want to store the user information in to not overload my user table (everything well sorted)

class AccountInformation < ApplicationRecord

   belongs_to :user

end

I have used wicked a couple of times and it always works but only if i store all the information in the user model... which i dont want to do this time because of a better structure and stuff.


Controller

users_controller.rb

class UsersController < ApplicationController

    def index
        redirect_to root_path
    end

    def create
        @user = User.create( user_params )
    end

    def show

        @user = User.find(params[:id])

        if user_signed_in?
            render 'show'

        else
            redirect_to root_path
        end
    end


    private
    def user_params
        params.require(:user).permit(:first_name, :accounttype, :accountinfo, accountinfos_attributes:[:user_id, :competence])
    end
end


user_steps_controller

class UserStepsController < ApplicationController
include Wicked::Wizard
steps :welcome

before_action :authenticate_user!


def show
        @user = current_user
        render_wizard
end

def create
        @accountinfo = @user.accountinfo.create(user_params)
end

def update  
        @user = current_user
        @user.update(user_params)

        render_wizard @user
end


private
def user_params
    params.require(:user).permit(:accountinfo,accountinfo_attributes:[:id, :competence])
end

private
def redirect_to_finish_wizard_path
    redirect_to root_path, notice: "Danke für deine Zeit!"
end

   end


   private
   def user_params
       params.require(:user).permit(:accounttype, 
       account_information_attributes:[:id, :competence])
   end

   private
   def redirect_to_finish_wizard_path
      redirect_to root_path, notice: "Danke für deine Zeit!"
   end

   end

Views

welcome.html.erb

       <%= form_for @user, url: wizard_path do |f| %>    
                <%= f.fields_for(:accountinfo) do |builder| %>
                    <div class="m-wizard__choose2 m-wizard__choose2--border-right">
                       <label>   
                            <%= builder.radio_button :competence, 1, class: "input-hidden" %>
                             <i class="icon-people-male h1"></i>
                            <p class="h6 m-text--bold">Designer</p>
                        </label> 
                    </div>

                    <div class="m-wizard__choose2">
                        <label>   
                            <%= builder.radio_button :competence, 2, class: "input-hidden" %>
                             <i class="icon-people h1"></i>
                            <p class="h6 m-text--bold">Texter</p>
                        </label>                  
                    </div>
                <% end %>

                <div class="m-text--center">
                    <%= f.submit "Weiter", class: "m-button" %>
                </div>
            <% end %>

Maybe you already found something ...

I want my user to come to the welcome.html.erb after the registration.

devise is working well, the redirection to the wicked controller as well. wicked does work properly as always, the routes are also set up correctly but this time I want my information of "competence" to be stored into the associated table of account_information.

After I press the "Weiter" ("continue" in German) button, nothing happens but the site re-renders. This is what my console outputs:

Processing by UserStepsController#update as HTML Parameters: {"utf8"=>"✓", "authenticity_token"=>"uYRJyCeBGyyDcWUtIj62fmT9oMpTnUQ3p+CSi3n8tSKKLguB1j/CPZaeuZCcmpCoBjJDKY6yz7/Z2wXfAO7YBg==", "user"=>{"account_information_attributes"=>{"competence"=>"1"}}, "commit"=>"Weiter", "id"=>"welcome"} User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT ? [["id", 12], ["LIMIT", 1]] (0.0ms) begin transaction AccountInformation Load (0.1ms) SELECT "account_informations".* FROM "account_informations" WHERE "account_informations"."user_id" = ? LIMIT ? [["user_id", 12], ["LIMIT", 1]] (0.1ms) rollback transaction (0.0ms) begin transaction (0.0ms) rollback transaction

enter image description here

2

There are 2 best solutions below

8
On

According to Wicket doc:

class AfterSignupController < ApplicationController
  include Wicked::Wizard

  steps :confirm_password, :confirm_profile, :find_friends

  def show
    @user = current_user
    case step
    when :find_friends
      @friends = @user.find_friends
    end
    render_wizard
  end
end

You should have somewhere a case step in your controller, which I'm not seeing in your current code.

Looks like a redirection issue

2
On

I found the solution. the problem was the missing create action and some other stuff. i edited the post, so you can read ist