ruby-on-railsdeviseacts-as-tenant

Rails Devise NoMethodError in Users::RegistrationsController#create undefined method `each_with_index' for #<Venue:0x00007fadb5270398>


I have a little app where i have changed account to venue and am now hitting an issue on user create with venue attributes

NoMethodError in Users::RegistrationsController#create undefined method `each_with_index' for #Venue:0x00007fadb5270398 RegistrationsController

class Users::RegistrationsController < Devise::RegistrationsController
  
  def new
    @user = User.new
    @user.build_venue
  end
end

User Model

class User < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :masqueradable, :database_authenticatable, :registerable, :recoverable, :rememberable, :validatable, :omniauthable
  acts_as_tenant(:venue)

  has_one_attached :avatar
  has_person_name

  has_many :notifications, as: :recipient
  has_many :services
  has_many :check_ins
  has_many :venue, through: :check_ins
  
  belongs_to :venue, inverse_of: :users
  accepts_nested_attributes_for :venue, reject_if: :all_blank, allow_destroy: true
end

Venue Model

class Venue < ApplicationRecord
    extend FriendlyId
    friendly_id :name, use: :slugged
    has_many :check_ins
    has_many :users, through: :check_ins
    has_many :guests, inverse_of: :venue
    accepts_nested_attributes_for :guests, reject_if: :all_blank, allow_destroy: true

    geocoded_by :address
    after_validation :geocode, if: ->(obj){ obj.address.present? and obj.address_changed? }
end

Sign Up Form

<div class="row">
  <div class="col-lg-4 col-md-6 ml-auto mr-auto">
    <h1 class="text-center">Sign Up</h1>

    <%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
      <%= devise_error_messages! %>

      <div class="form-group">
        <%= f.text_field :name, autofocus: true, class: 'form-control', placeholder: "Full Name" %>
      </div>

      <div class="form-group">
        <%= f.email_field :email, autofocus: false, class: 'form-control', placeholder: "Email Address" %>
      </div>
      <%#= f.hidden_field :accountrole, value: 'admin'%> 
      <%= f.fields_for :venue do |af| %>   
        <div class="form-group">
          <%= af.text_field :name, class: 'form-control', placeholder: "Venue Name" %>
        </div>
      <% end %>
      <div class="form-group">
        <%= f.password_field :password, autocomplete: "off", class: 'form-control', placeholder: 'Password' %>
      </div>

      <div class="form-group">
        <%= f.password_field :password_confirmation, autocomplete: "off", class: 'form-control', placeholder: 'Confirm Password' %>
      </div>

      <div class="form-group">
        <%= f.submit "Sign up", class: "btn btn-primary btn-block btn-lg" %>
      </div>
    <% end %>

    <div class="text-center">
      <%= render "devise/shared/links" %>
    </div>
  </div>
</div>

What is causing my error?

Update

Application Controller

class ApplicationController < ActionController::Base
  set_current_tenant_by_subdomain(:venue, :subdomain)
  
  include Pundit

  protect_from_forgery with: :exception

  before_action :configure_permitted_parameters, if: :devise_controller?
  before_action :masquerade_user!

  protected

    def configure_permitted_parameters
      devise_parameter_sanitizer.permit(:sign_up, keys: [:name, :organisation, :phone, :email, :active, :accountrole, venue_attributes: [:name, :id]])
      devise_parameter_sanitizer.permit(:account_update, keys: [:name, :avatar])
      devise_parameter_sanitizer.permit(:invite, keys: [:name, venue_attributes: [:id]])
    end
end

Solution

  • Since you're adding venue attributes to the user registration form, you may need to add these attributes to the strong_parameters list so they can be passed to the RegistrationsController#create action.

    Devise's documentation shows how to do this: https://github.com/heartcombo/devise#strong-parameters