Rails Friendly_ID Multiple model creation with slug on same field failing - ruby-on-rails

I am running a Rails 5 application which has 2 models - a User and a Provider. I am using multiple table inheritance to show that each Provider "is a" User (via the active_record-acts_as gem). So, in effect, creating a Provider with the related fields would create a User at the same time.
I wanted to implement slugging for these models, so I integrated the friendly_id gem for that purpose.
Both models are slugged via a field called username. The code in question being:
class User
extend FriendlyId
friendly_id :username, use: :slugged
# ...
end
for the User model and
class Provider
extend FriendlyId
friendly_id username, use: :slugged
def username
acting_as.username # this fetches the parent model (User)'s username field.
end
# ...
end
for the Provider model.
When I attempt to create a Provider via a controller action (providers#create), it fails, with the error being:
TypeError at /providers
nil is not a symbol nor a string
The stack trace identifies the problem to be at lib/friendly_id/slugged.rb:299, which is the body of the should_generate_new_friendly_id? method. This method was called by the set_slug method in the same file, slugged.rb.
I have created an issue on the GitHub page of friendly_id, where you can find the request parameters and full stack trace.
Edit: added friendly_id_config for both: https://gist.github.com/mindseyeblind/9b78c588f5008a494f7157e72da1de6e

Related

How to avoid FriendlyId creating a different slug if current already exists

I'm using FriendlyId gem on Ruby on Rails 5.
Is there any way to stop FriendlyId to create a different slug if the current one has already been taken? I'd like the user to have full control over the slug.
Add this method to your Model.
def should_generate_new_friendly_id?
new_record?
end
or modify the content of the method to match your needs.

Build vanity urls with variables stored in a different table from the model

I am trying to build vanity urls with FriendlyId gem for a specific model Teacher to display
www.mysite.com/teachers/{first_name}-{last_name}
instead of
wwww.mysite.com/teachers/{id}
The problem that I encounter is that the information on the {first_name} / {last_name} is stored in the table Contact accessible through User and not in Teacher's one. The relation between the tables is as follows:
- Teacher belongs_to :user
- User has_one :contact
I added in my Teacher model:
extend FriendlyId
friendly_id :full_name_to_url, use: :slugged
So FriendlyId calls the method full_name_to_url to create the slug:
def full_name_to_url
"#{self.user.contact.first_name.downcase.gsub(" ","-")}-#{self.user.contact.last_name.downcase.gsub(" ","-")}"
end
I received the following message when trying to apply and save all the changes to the already existing records: Teacher.find_each(&:save)
NoMethodError: undefined method `contact' for nil:NilClass
I guess there is something wrong with my method?

rails friendly_id bad request

I'm new to rails and currently involved in an internship and I was assigned to use the friendly_id gem for my tournament class, this is part of the code in it:
class Tournament < ApplicationRecord
extend FriendlyId
friendly_id :url_id
...
end
I don't use a slug since I have a url_id attribute that stores my desired url and when I try with the old .../tournaments/1 everything's all good but with .../tournaments/example I get "example is not a valid value for id" with code 103, status 400. Any ideas what the problem might be?
You have to update your controller for Tournaments so that it uses friendly.find method instead of the find.
# Change this:
Tournament.find(params[:id])
# to
Tournament.friendly.find(params[:id])

Change the unique generated title names of friendly-id using attribute of another table

I have a Company Model, and i am using friendly_id like this
friendly_id :name, use: :slugged
But since there can be many Company with the same name (different branches). I am trying to handle that case by using city attribute from the address of the Company.
But the Company address is stored in a different table Address.
so company.address.city gives me the city of the company.
friendly_id :slug_candidates, use: :slugged
# Try building a slug based on the following fields in
# increasing order of specificity.
def slug_candidates
[
:name,
[:name, :city]
]
end
I'm aware i can do something like above. But since city is not an attribute of company how can i achieve this?
Update:
Possible solution for this is to create a helper method city which returns the company's city.
But the problem never was that.
The version of friendly_id i am using is 4.0.10.1
and the feature which enables the usage of slug_candidates are available in versions 5 and above.
I tried updating the gem. But it wont get updated as version 5 has dependency on activerecord 4.0 and rails has dependency on activerecord 3.2.13
It's kind of a deadlock. Don't know what to do
class Company < ActiveRecord::Base
.............................
def city
self.address.city
end
end

Is there a way that the :reserved_words option for models in FriendlyId gem does not overwrite the Rails defaults?

I have the default friendly_id configuration in place in my project, which without comments looks like this:
FriendlyId.defaults do |config|
config.use :reserved
config.reserved_words = %w(new edit index session login logout users admin stylesheets assets javascripts images)
end
And a model which has this configuration:
EXCLUDED_SLUG_VALUES = %w(users articles authors topics admin your all)
friendly_id :name, use: :slugged, reserved_words: EXCLUDED_SLUG_VALUES
This is because the model is accessible through this route: /:id
My problem is that the model configuration overwrites the defaults in the config file. I can create the model with a name: 'new' and the slug will be set to 'new', while it will not work for other models.
I wasn't expecting this to be the default behaviour. Is there a way to have the defaults active while adding specific reserved words to a model?
Each model that extends FriendlyId gets its own copy of the friendly_id configuration that you can manipulate. You can access (and modify) this configuration using friendly_id_config.
So you could concat your additional list of EXCLUDED_SLUG_VALUES onto the reserved_words, like this:
class MyModel < ActiveRecord::Base
extend FriendlyId
EXCLUDED_SLUG_VALUES = %w(users articles authors topics admin your all)
friendly_id_config.reserved_words.concat(EXCLUDED_SLUG_VALUES)
friendly_id :name, use: :slugged
end
All of your models will continue to use the reserved words you specified in the default configuration, and MyModel will additionally reserve EXCLUDED_SLUG_VALUES.

Resources