when using rails_admin for associated objects (like has_and_belongs_to) it shows the ID of the object as the association.
This isn't a great deal for the users so I'ld like to change this for showing the text of the associated object.
Is this solvable?
Here a little example:
First Model:
class Menu
include Mongoid::Document
field :date, type: Date
has_and_belongs_to_many :meal
end
Second Model:
class Meal
include Mongoid::Document
field :text, type: String
has_and_belongs_to_many :menu
end
So it shows something like this:
But I'ld love to see the Text of the meals instead.
Simply define a title-method do the trick:
def title
self.text
end
You could use the RailsAdmin DSL object_label_method to change how the field is presented to the user.
In your case, something like this might do the trick:
RailsAdmin.config do |config|
config.model Menu do
list do
field :meal do
pretty_value do
value.text
end
end
end
end
end
Related
I'm trying to make a form to create new record for a model user which has one billing_information. Billing_information has an attribute account_name that I want to include in the form. I tried using the delegate method but it's not working. It produces :-
error: unknown attribute 'billing_information_account_name' for User.
class User < ActiveRecord::Base
accepts_nested_attributes_for :billing_information
has_one :billing_information, inverse_of: :user
delegate :account_name, to: :billing_information, allow_nil: true
rails_admin do
create do
field :name
field :email
field :billing_information_account_name do
def value
bindings[:object].account_name
end
end
end
end
end
Does anyone has a better solution? Thank you.
Sadly, you won't get help from rails admin in this case, but it can be done.
You have to add a new virtual field and handle in a setter the input. Take a look at this example.
class User < ApplicationRecord
has_one :billing_information, inverse_of: :user
# A getter used to populate the field value on rails admin
def billing_information_account_name
billing_information.account_name
end
# A setter that will be called with whatever the user wrote in your field
def billing_information_account_name=(name)
billing_information.update(account_name: name)
end
rails_admin do
configure :billing_information_account_name, :text do
virtual?
end
edit do
field :billing_information_account_name
end
end
end
You can always create the full billing_information using the nested attributes strategy, meaning add the billing_information field and you'll get a nice form to fill all the information.
I have categories and articles. They have a HABTM relation. I would like the possibility of listing each category and the articles that have relation to that article in the list view of articles.
How can I accomplish this?
I have tried with scopes, however this require a function?
https://github.com/mathieul/rails_admin
I would create a custom method and then include in fields
class Article
include Mongoid::Document
field :title, type: String
field :body, type: String
has_and_belongs_to_many :categories
def category_articles
output = []
categories.each do |cat|
output << cat.articles.pluck(:title)
end
return output.flatten.join(', ')
end
rails_admin do
list do
include_all_fields
field :category_articles
end
end
end
I have models User and Article.
User has the following associations:
class User < ActiveRecord::Base
has_many :articles
and Article's:
class Article < ActiveRecord::Base
belongs_to :user, required: true
I use rails_admin as a control panel and customize a required fields in rails_admin.rb as follows:
config.model Article do
list do
field :id
field :title
field :user_id
field :created_at
end
end
But how to implement that instead of :user_id displays the name of the user? I have a username field in my database.
Thanks!
In your Article model, you can add a custom method that will return the user_name:
def user_name
self.user.username
end
Then, you can use this user_name field in your admin like other model attributes:
config.model Article do
list do
field :id
field :title
field :created_at
field :user_name
end
end
Here's another stab at it...
Rails_admin looks for a "name" or "title" field on the model, if there are none, it will display a somewhat ugly "User#1".
All you need to do in your User Model is to add the following method:
def title
try(:username)
end
I like to go back to this presentation for Rails Admin's best practices: http://www.slideshare.net/benoitbenezech/rails-admin-overbest-practices
It's a bit dated but everything you need is there (around page 14 for your case)
In my project I am using RailsAdmin and have two models, Product & Product_rate.
has_many :product_rates
belongs_to :product
The code in rails_admin.rb is
config.model Product do
....
list do
field :product_rates
end
I want show the product_rates' rank in the "field :product_rates". The product_rate model looks like this.
class ProductRate < ActiveRecord::Base
belongs_to :product
attr_accessible :rank, :product_id
end
The best results can be displayed the rank sum.
For example: Product XX has ranks what are 0,1,0,2. I want to show rank sum in the product_rates, which would be 3.
Any help is appreciated. Thanks
How about you add a total_rank method to your Product model and use that.
class Product < ActiveRecord::Base
has_many :product_rates
def total_rank
product_rates.map(&:rank).inject(:+)
end
end
Then in your initializers/rails_admin.rb:
config.model Product do
....
list do
field :total_rank do
label "Rating"
end
end
Maybe that doesn't exactly answer your question. According to the docs maybe you want to try something like this..
list do
field :product_rating do
formatted_value do # used in form views
value.map(&:rank).inject(:+) # I'm assuming the value is an array of products
end
end
end
Having two models: Car (e.g Audi, Mercedes) and Option (ABS, Laser Headlights, Night Vision ...). Car habtm options.
Suppose both for Audi and Mercedes "Night Vision" option is available.
But to have it in Mercedes you need to pay some extra money for this option. So as I'm guessing I need to extend somehow my Option model to store options's extra price for some cars. Car model I think should also be modified. But can't imagine how.
My aim to achieve behaviour something like this:
Audi.options.night_vision.extra_price => nil
Mercedes.options.night_vision.extra_price => 300
Of course I don't want to duplicate "Night Vision" option in options collection for every car.
Thanks.
This is neither the simplest, or most elegant, just an idea that should work based on assumptions on how you may have implemented the options. Please come back to me if you need more help.
To achieve audi.options.night_vision.extra_price I assume that you have a models such as:
class car
include Mongoid::Document
field :name, type: String
has_and_belongs_to_many :options do
def night_vision
#target.find_by(name:'night_vision')
end
end
end
class option
include Mongoid::Document
field :name, type: String
field :extra_price, type: Float
has_and_belongs_to_many :cars
end
This would enable you to do:
audi = Car.find_by(name:'audi')
audi.options.night_vision.extra_price
If the above assumptions are correct, you should be able to mod your classes like so:
class option
include Mongoid::Document
attr_accessor :extra_price
field :name, type: String
has_and_belongs_to_many :cars
embeds_many :extras
end
class extra
include Mongoid::Document
field :car_id, type: String
field :price, type: String
embedded_in :option
end
class car
include Mongoid::Document
field :name, type: String
has_and_belongs_to_many :options do
def night_vision
extra = #target.find_by(name:'night_vision')
extra_price = extra.prices.find_by(car_id: #target._id.to_s) if extra
extra.extra_price = extra_price.price if extra && extra_price
return extra
end
def find_or_create_option(args)
extra = #target.find_or_create_by(name:args)
price = extra.extras.find_or_create_by(car_id:#target._id.to_s)
price.set(price: args.price
end
end
end
This should then enable you to populate your options like:
audi.options.find_or_create_option({name:'night_vision', price:2310.30})
bmw.options.find_or_create_option({name:'night_vision', price:1840.99})
audi.options.night_vision.extra_price
=> 2310.30
bmw.options.night_vision.extra_price
=> 1840.99
And if you attempted to find night_vision on a car that did not have night_vision you would get:
skoda.options.night_vision
=> nil
skoda.options.night_vision.extra_price
=> NoMethodError (undefined method 'extra_price' for nil:NilClass)