Rails STI and strong options

I have a client resource with two types: Person and Company.

routes.rb:

resources :clients
resources :people, :controller => "clients", :type => "Person"
resources :companies, :controller => "clients", :type => "Company"

clients_controller:

def new
  @client = Client.new()
  @client.type = params[:type]
end

def create
  @client = current_partner.clients.new(client_params)
  if @client.save
    redirect_to clients_path
  ...
end

...
private
def client_params
  params.require(:client).permit(:type, :partner_id, :name, :email, :phone, :cui,   :registration_id, :address)
end

def find_client
  @client ||= Client.find(params[:id])
end

client.rb

class Client < ActiveRecord::Base
  validates_presence_of :type
  CLIENT_TYPES = ['Person', 'Company']
end

person.rb

class Person < Client
  validates_presence_of :name, :email, :phone
end

compay.rb

class Company < Client
  validates_presence_of :name, :email, :cui, :registration_id, :phone
  validates_uniqueness_of :cui, :registration_id, uniqueness: {scope: :partner_id}
end

The problem is when I try to edit the client details, and I submit the changes, I get the parameter is missing or the value is empty: the client. The route where I get this error is ... / company / 3.

Any help on this noobie? Thank!

+4
source share
6 answers

You can mask your inherited model to the parent before the permission action

def client_params

  if params.has_key? :person
    params[:client] = params.delete :person
  elsif params.has_key? :company
    params[:client] = params.delete :company
  end

  params.require(:client).permit(...)

end

Simple renaming of the model key in the params hash and trick.

+6
source

Models

, STI

STI Model s, controllers. MVC Models . user views:

enter image description here

, STI , classes ( , type ..):

#app/models/person.rb
Class Person < Client
   ...
end

#app/models/company.rb
Class Company < Client
end

#app/models/client.rb
Class Client < ActiveRecord::Base
end

:

#config/routes.rb
resources :clients
resources :people,    controller: "clients", type: "Person"
resources :companies, controller: "clients", type: "Company"

#app/controllers/clients_controller.rb
Class ClientsController < ApplicationController
    def create
       model = get_model(params[:type])

       @model = model.new(model_params)
       @model.save
    end

    private

    def get_model type
       return type.singularize.titleize.camelize.constantize
    end

    def model_params
        params.require(params[:type].to_sym).permit(:client, :model, :attributes)
    end
end

STI Model, , /people /companies, ( Client type, )

+3

, Ran. params , require.

def client_params
  key = (params.keys & %w(person company))[0]
  params.require(key).permit(.....)
end
+2

, ClientsController . client_params ClientsController, : params.require hash (params.require(: client)), , paramsrequire (: ) ; , params.require params.require(: company), , .

, , , , , :

def client_params
  # This is not good, by virtue of the fact that you're using one controller
  # to handle multiple models.
  params.require(params[:type].try(:downcase) || :client).permit(:type, :partner_id, :name, :email, :phone, :cui, :registration_id, :address) 
end

, (, BaseApplicationController < ApplicationController), , . , - , . "client_params" .

.

+1
private
def client_params
  params.require(params[:type].try(:downcase) || :client).permit(:type, :partner_id, :name, :email, :phone, :cui, :registration_id, :address) 
end
0

I had a similar problem when I have a company model, a subclass of User model and Owner, Administrator, Analyst, etc., in my company model I have accepts_nested_attributes_for: user and: user_attributes [: att ,: att2] in strong the parameters allow, but I needed to add the model name as the allowed parameter.

What I had at the beginning

def company_params
    params.require(:company).permit(:coname, :industry, :users_attributes => [:id, :first_name, :last_name, :email, :password, :password_confirmation, :type])
end

Addendum: owner, made it work for me.

def company_params
    params.require(:company).permit(:coname, :industry, :owner, :users_attributes => [:id, :first_name, :last_name, :email, :password, :password_confirmation, :type])
end
-1
source

All Articles