How to order foreign key values in Django admin?
ex:
class LeaveBase(models.Model):
User = models.ForeignKey(User,verbose_name=('User Name'))
FinancialYear=models.ForeignKey(FinancialYear,verbose_name=('Financial Year'))
In my Django admin when i add a new leavebase the User column shows as select box with the default ordering by id, I would like to order by its name.
this may help: http://www.djangoproject.com/documentation/models/ordering/
Related
Hi guys I have a couple of foreign keys in a table A and i Would Like to select a specific column in table B to be shown to the user instead of the column b id's.
Maybe the picture helps understanding:
Here, instead of shown Tag #1, Tag #2, Tag #3, Tag #4 I would like to shown the column name of each of these Tags.
By default rails admin uses the name attribute of an instance to display them.
But i think is better practice to give them their own rails admin specific name as often you'll want the name to be relevant to your operations team and not necessarily to your end users,
With that said you can tell rails admin what method to use adding this line on the initializer config file.
RailsAdmin.config {|c| c.label_methods << :rails_admin_title }
And then you would implement that instance method on your tag model
class Tag < ApplicationRecord
def rails_admin_title
"#{self.name} #{self.id}"
end
end
Right now for my rails app (using devise and active admin), I am having user ids as serial numerals depending upon the serial of user id creation, i.e. first time I got user id 1, then again signed up with different details and then got user id 2 and then 3 and so on.
But I want to have custom user ids, like greg51 or michel7as or something like that asked during user signup page
How do I do it?
If you want to login with a username or an email, just follow devise instructions in: https://github.com/plataformatec/devise/wiki/How-To:-Allow-users-to-sign-in-using-their-username-or-email-address.
If you want to find a user using other fields you can #user.find_by(username: params[:username]) or whatever field you want in your controllers.
However, you should not change the id for a new field (username, email or whatever). Rails generates an id in all tables it creates and uses the id as a primary key. The primary key should never be changed as it will be used in other tables as references. For this purpose, it uses a sequence field in the database, which creates unique integer values (it increments the last sequence value and returns it as the new id) and guarantees that several transactions cannot get the same value (so no other record will have the same id).
Besides the primary key, you can define many other unique fields, such as username, email, document_id, etc. Although these fields can also be unique (and can be forced to be unique using a database constraint and the validates uniqueness in rails, they are not used as primary key (so you can change them later and no references will be affected).
What you want is called vanity URLs where you let the users provide a more human friendly identifier for use in URLs. The column used is often called the slug column.
This is not a replacement for primary key ids, either in the form of an auto-incrementing integer column or UUIDs which is basically the same thing but it uses a random generated string instead to solve problems related to scalability. Primary keys are how your database tables refer to one another. Replacing it with a user generated value is possible but not a good idea at all.
To add a "username" feature in Devise you need to:
Add the username column with a migration. Make sure it has a unique constraint.
Validate and ensure that the username is URL safe and unique.
Alter the way Warden looks up users from the database to use the id or username column.
Change the way devise looks up users in its controllers to use the id or username column.
See:
Devise WIKI: Allow users to sign in using their username or email address
Stringex - library for slugging strings
Friendly-id - the “Swiss Army bulldozer” of slugging and permalink plugins for ActiveRecord.
Add a field to your user model:
rails g migraton AddUsernamaToUser username:string
Then add a field to your devise form:
https://github.com/plataformatec/devise/issues/4201
And you'll be able to ask for a username.
I have two Models User and Site. The User has category like 'basic and premium'. The user has relation to sites one -> many (i.e one user can have more than one sites). Now i want to select sites of premium user. Can someone tell me how to use where clause in ActiveRecord to achieve this?
I want to select sites of premium user
This will do
User.includes(:sites).where('users.category = ?', 'premium')
Update
If sites also have categories like 'wordpress or joomla', how do i
apply where clause to select only wordpress sites of premium users
For that you need to tweak the query like this
User.includes(:sites).where('users.category = ? and sites.category = ?', 'premium','wordpress')
As you said that category is a column, so Rails automatically generates the following method for you:
User.find_by_category("basic")
If you do not want to use this, you can use where method, in which you have to send a key-value pair like following:
User.where(:category => "basic")
And when you have found a user with the category you desired, you can simply call sites on it to get all the associated sites with a particular user.
You can try this also:
#user_ids = User.where(category: 'premium').pluck(:id)
#sites = Site.where(user_id: #user_ids)
My question is the following:
I have two models : Products & brands.
Currently in the product form, the user is able to pick up a brand (via a select list) for his product. But if the brand doesn't exist he can create a new one by clicking on a link redirecting to the brands/new form.
Is there any way to handle the missing brand creation directly in the product formular ?
I hope I'm clear enough.
Thanks for your answers.
In the form itself, you could allow the user to either select the brand from a dropdown or type the name of a new brand in a text field. I would use radios to force the user to perform one of those two actions, not both. The <option> elements would have a value corresponding to the brand name rather than the brand ID.
Then, on the Rails side, you could use find_or_create_by_name, assuming your brand names are unique:
# assuming a params structure like params[:product][:brand_name]
class Product < ActiveRecord::Base
def brand_name=(name)
self.brand = Brand.find_or_create_by_name(name)
end
end
The controller would still simply do something like this:
#product = Product.new(params[:product])
I would personally use jQuery for something like this. Have the user select something like "New Brand" from the select list and then display an input prompt. Use AJAX to create the new brand and then recreate the brand list in the form with the new brand selected.
I have installed Devise and created Users and also Admins using Option 1 from this tutorial https://github.com/plataformatec/devise/wiki/How-To:-Add-an-Admin-role
Now I need a little help. When adding the Admins it creates a different table, and the potential arises that the admins and regular users could have the same ID's.
So how exactly do I got about grabbing information from users and admins? Say for example I want to display all users? Do I have to traverse the users table and then the admins table?
Or if I am displaying a post. How will I know which table to look for to get the user or admin info?
I know I can just add a role column to the users table but I wanted to avoid this.
I hope this makes sense haha
I highly recommend using the Single Table Inheritance (STI). You could do the STI by adding a column named type with a string datatype in the users table and create an admin model as well as a normal_user model both models will inherit from the user model of the devise gem.
class NormalUser < User
end
class Admin < User
end
The type column is a reserved word which will hold a value either NormalUser or Admin according to the user type you created.
To create an admin use Admin.create(...) and to create a normal user use NormalUser.create(...) where the dots are the attributes of the Admin and the NormalUser