Model with acts_as_tenant fails validation after Rails 5 update - ruby-on-rails-5

rails 5.2.1 ruby 2.5.1
My Model
class InputForm < ApplicationRecord
acts_as_tenant(:tenant)
end
InputForm.validators shows
#<ActiveRecord::Validations::PresenceValidator:0x000000000baaae28
#attributes=[:tenant],
#options={:message=>:required}>
This is not allowing me to create the InputForm without tenant.
Note : I don't have any config setup (config.require_tenant = true )
or file like config/initializers/acts_as_tenant.rb
What i'm doing wrong ?

Have you tried the optional: true options when specifying acts_as_tenant?
class InputForm < ApplicationRecord
acts_as_tenant :tenant, optional: true
end
OR
You can configure your rails 5 application like so
# config/application.rb
...
module YourProject
class Application < Rails::Application
...
# Make the belongs_to value as false by default in Rails 5
config.active_record.belongs_to_required_by_default = false
...
end
end
Responded here as well.
https://github.com/ErwinM/acts_as_tenant/issues/196#issuecomment-460605781

Related

Delete a Post without the associated Task

I would like to be able to destroy my Post without the Task which is associated. But I'm currently facing a SQL error which say:
ActiveRecord::InvalidForeignKey (SQLite3::ConstraintException: FOREIGN KEY constraint failed: DELETE FROM "posts" WHERE "posts"."id" = ?):
After a few search, I saw that is coming from associations and Foreign Key. But I cannot solve the problem for the moment.
I have tested to put (optional: true) into my model.
I also have tried to change the foreign key into (, on_delete: :cascade) & (, on_delete: :nullify) but it's still not working.
My code =
//Post Model
class Post < ApplicationRecord
has_one :task
end
//Task Model
class Task < ApplicationRecord
belongs_to :post, optional: true
end
To destroy :
//Destroy_one into the Post Controller
def destoy_one
#post.destroy
end
Migration File : (also tried with on_delete: :nullify)
class EditForeightKeys < ActiveRecord::Migration[5.1]
def change
# remove the old foreign_key
remove_foreign_key :tasks, :post
# add the new foreign_key
add_foreign_key :tasks, :post, on_delete: :cascade
end
end
Do you have any other solution for that ?
I solve this issue by implement a deleted_state into Posts
def destroy_one
#post.update(deleted_state: true)
end
And after you can put a default scope into your Post model like this :
default_scope { where(deleted_state: false) }
Like this all will work without problems !!
You can use callbacks on destroy action for User as a variant:
class Post
before_destroy :update_tasks
private
def update_tasks
self.tasks.update_all(post_id: nil)
end
end

default values for Virtus in rails

I am using virtus(1.0.5) with rails (5.0.2). I am using Virtus for a model since it has validations based on the page being accessed.
My Organization model is as
class Organization < ApplicationRecord
validates :name, presence: true
end
and form created using virtus is as
class OrganizationProfileForm
include ActiveModel::Model
include Virtus.model
attribute :call_center_number, String, default: :org_call_center_number
validates :call_center_number, presence: true
def initialize(organization)
#organization = organization
end
private
def org_call_center_number
#organization.call_center_number
end
end
Unfortunately, the above code doesn't work
Loading development environment (Rails 5.0.2)
2.3.0 :001 > of = OrganizationProfileForm.new(Organization.last)
Organization Load (0.6ms) SELECT "organizations".* FROM "organizations" ORDER BY "organizations"."id" DESC LIMIT $1 [["LIMIT", 1]]
=> #<OrganizationProfileForm:0x007f9d61edd6a8 #organization=# <Organization id: 1, name: "Some name", call_center_number: "4892374928", created_at: "2017-03-29 09:35:22", updated_at: "2017-03-29 09:37:59">>
2.3.0 :002 > of.call_center_number
=> nil
We need to call super() in the initialize method.
Try removing the line private, as this may be preventing the call to the method org_call_center_number. The example given for default values on the Virtus repo uses a public instance method, not a private one.
See: What are the differences between "private", "public", and "protected methods"?

Rails 3 & Strong Parameters, getting mass assignment errors

I'm trying to use strong parameters in a single model in my Rails 3 project that has around 40-50 models.
I've done the following, but when I try to create or update an instance of this model, I get the same error regarding mass assignment, as below, which shows every field of the model.
I've tried removing the accepted_nested_attributes_for from the model and restarting the webserver, but it didn't have an effect on the error I'm receiving.
config/application.rb
config.active_record.whitelist_attributes = false
app/models/my_service.rb (concatenated for brevity)
class CallService < ActiveRecord::Base
include ActiveModel::ForbiddenAttributesProtection
belongs_to :account
has_many :my_service_chargeables
accepts_nested_attributes_for :my_forward_schedules, allow_destroy: true
validates :start_date, :username, :account_id, :plan_id, presence: true
audited associated_with: :account
scope :enabled, where(enabled: true)
scope :within, lambda{|month| where(start_date: (month.beginning_of_month..month.end_of_month))}
end
app/controllers/my_services_controller.rb
def update
#my_service = MyService.find(params[:id])
if #my_service.update_attributes(permitted_params.my_service)
flash[:success] = "Service Updated"
redirect_to #my_service
else
render 'edit'
end
end
app/controllers/application_controller.rb
def permitted_params
#permitted_params ||= PermittedParams.new(current_user, params)
end
app/models/permitted_params.rb
class PermittedParams < Struct.new(:user, :params)
def my_service
if user && user.role?(:customer)
params.require(:my_service).permit(*service_customer_attributes)
else
params.require(:my_service).permit!
end
end
def service_customer_attributes
[:timeout, :pin, :day]
end
end
ERROR WHEN UPDATING
ActiveModel::MassAssignmentSecurity::Error in MyServicesController#update
Can't mass-assign protected attributes: account_id, plan_id, start_date, username
I've run a debugger to confirm the code hits the params.require(:my_service).permit! line from the PermittedParams class, yet this exception still keeps getting thrown, when as far as I can tell, there should be nothing causing this model to require declaring attributes as attr_accessible's.
Can anyone shed some light on this behavior?
I'm using gem versions (from my Gemfile.lock):
strong_parameters (0.2.0)
rails (3.2.11)
I'm not sure what your exact use case is, but doing params.require(:my_service).permit! still seems like a bad idea here, at the very least someone could still override your model's PK. Rather than params.require(:my_service).permit! why not do:
params.require(:my_service).permit(:timeout, :pin, :day, :account_id,
:plan_id, :start_date, :username)
Or keep these in another array and merge them with your existing service_customer_attributes to keep it DRY.
This would take care of your mass assignment error, and will be more secure and more explicit.

Accessing Rails Helper files from models

I am trying to validate the input of a state field using:
include ActionView::Helpers
class Credentials < ActiveRecord::Base
attr_accessible :license_number, ...:address_zip_code,
...
validates :license_number, presence: true, length: { minimum: 4 }
...
validates_inclusion_of :current_practice_address_state, :in => state_list
end
The variable state_list is an array described in helpers/credentials_helper.rb
Testing the model I run into undefined local variable error
$ bundle exec rspec spec/models/credentials_spec.rb
in `method_missing': undefined local variable or method `state_list' for #<Class:0x007f86a1844250> (NameError)
The helper class looks like:
module CredentialsHelper
state_list = %w(AL AK...WY)
end
Your call to include has to be inside the class:
class Credentials < ActiveRecord::Base
include ActionView::Helpers
...
end

uuidtools, rspec and Rails 3

I'm working with the UUIDTools gem in Rails 3 and running into some problems. It seems to work fine in practice:
> item = Item.create
=> #<Item uuid: "e9d00043-9200-4497-a55c-509c5de3dd88", created_at: "2012-01-09 01:56:49", updated_at: "2012-01-09 01:56:49">
> item.id
=> "e9d00043-9200-4497-a55c-509c5de3dd88"
But then in my specs it tells a different story:
require 'spec_helper'
describe Item do
it 'should assign an id' do
item = Item.create
puts "item id: #{item.id}"
end
end
Running this spec shows:
item id: 5
.
Finished in 2.21 seconds
1 example, 0 failures
Where's my guid? There doesn't seem to be any pattern to what id is assigned, I've run this a bunch of times and seen it go anywhere from 0 to up in the thousands.
Here is my migration:
class CreateItems < ActiveRecord::Migration
def change
create_table :items, :id => false do |t|
t.string :uuid, :null => false, :primary => true
t.timestamps
end
add_index :items, :uuid, :unique => true
end
end
My model:
require 'uuid_helper'
class Item < ActiveRecord::Base
include UUIDHelper
end
And my uuid_helper:
module UUIDHelper
def self.included(base)
base.class_eval do
set_primary_key :uuid
attr_readonly :uuid
before_create :set_uuid
private
def set_uuid
self.uuid = UUIDTools::UUID.random_create.to_s
end
end
end
end
Putting some debugger logic into set_uuid I've discovered that it's doing to_i on the uuid at some point. Any suggestions?
Update This seems to be a bug in the Rails test environment. When I run RAILS_ENV=test rails console I get the same behavior as in the specs--the guids are chopped off.
Alright, the answer was to upgrade to Rails 3.1.3 from 3.1.1.