How to change field's answer when I use gem 'rails_admin'? - ruby-on-rails

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

Related

Using sunspot to search down model hierarchy

Example:
I have the following:
class Person < ActiveRecord::Base
has_many :educations
end
class Education < ActiveRecord::Base
belongs_to :school
belongs_to :degree
belongs_to :major
end
class School < ActiveRecord::Base
has_many :educations
# has a :name
end
I want to be able to return all people who went to a specific school so in my PeopleController#index I have
#search = Person.search do
keywords params[:query]
end
#people = #search.results
How do I create the searchable method on the Person model to reach down into school? Do I do something like this:
searchable do
text :school_names do
educations.map { |e| e.school.name }
end
end
which I would eventually have to do with each attribute on education (degree etc) or can I make a searchable method on Education and somehow "call" that from Person.searchable?
Thanks
It would be best if you keep the declaration of all the indexed fields for an specific model in the same place.
Also, you were doing a good job indexing :school_names, just do the same thing for the rest of the associations fields' that you want to index.

Rails accept_nested_attributes still throws "Can't mass-assign protected attributes"

I think I'm either missing something really simple or something really obscure. Hoping someone can spot it for me or explain my muppetry.
Ok, So there are two models, Basket and BasketItem.
I've set Basket to accept_nested_attributes :basket_items with the intention of using fields_for in an edit view of Basket.
However when run up it still screams that
Error: Can't mass-assign protected attributes: basket_items_attributes
For the sake of this question I've boiled down to the same issue if I do a manual basket.update_attributes in the console with just one or two basket_item attributes. So I know it's a model issue, not a view or controller issue.
e.g.:
basket.update_attributes("basket_items_attributes"=>[{"qty"=>"1", "id"=>"29"}, {"qty"=>"7", "id"=>"30"}])
or similarly with a hash more like fields_for makes
basket.update_attributes( "basket_items_attributes"=>{
"0"=>{"qty"=>"1", "id"=>"29"},
"1"=>{"qty"=>"7", "id"=>"30"}
})
I've ensured that the associates in defined before the accepts_nested_attibutes_for, that the child model has the appropriate attributes accesable too, tried removing additional attributes for the nested data, lots of fiddling to no avail.
basket.rb
class Basket < ActiveRecord::Base
has_many :basket_items
attr_accessible :user_id
accepts_nested_attributes_for :basket_items
belongs_to :user
def total
total = 0
basket_items.each do |line_item|
total += line_item.total
end
return total
end
# Add new Variant or increment existing Item with new Quantity
def add_variant(variant_id = nil, qty = 0)
variant = Variant.find(variant_id)
# Find if already listed
basket_item = basket_items.find(:first, :conditions => {:variant_id => variant.id})
if (basket_item.nil?) then
basket_item = basket_items.new(:variant => variant, :qty => qty)
else
basket_item.qty += qty
end
basket_item.save
end
end
basket_item.rb
class BasketItem < ActiveRecord::Base
belongs_to :basket
belongs_to :variant
attr_accessible :id, :qty, :variant, :basket_id
def price
variant.price
end
def sku
return variant.sku
end
def description
variant.short_description
end
def total
price * qty
end
end
As the error says, you just need to add basket_items_attributes to your list of accepted attributes.
So you'd have
attr_accessible :user_id, :basket_items_attributes
at the top of your basket.rb file

How to override enumeration data in rail_admin gem

In my models, BookHeader has many Category
So, when edit or create new BookHeader, the form show like this
Enum fix?
I wanna change the "category #{id}" to category name by define a category_enum method but it still don't work. Please help!
Code for BookHeader model
class BookHeader < ActiveRecord::Base
attr_accessible :autho, :category_id, :description, :title, :book_type, :year,:publisher_id,:detail
has_many :books
belongs_to :category
belongs_to :publisher
TYPE = {:ebook=>"Ebook",:paper_book=> "PaperBook",:magazine=> "Magazine",:media=> "Media"}
DEFAULT_TAB = :paper_book
BOOKS_PER_PAGE = 1 # books to show in a pages (pagination)
extend FriendlyId
def book_type_enum #it worked here
TYPE.map{|key, val| [val]}
end
def category_enum #but dont' work here
["a","b"]
end
Code for edit form
edit do
field :title
field :description, :text do
ckeditor do true end
end
field :autho
field :book_type
field :category
end
See the Division attribute in this link
alias_attribute :name, :you_field_you_want_to_display
I think it's more flexible way, there is no need to rename something and everything will work properly
Yeah, I just found the answer, rename a column in your model to "name", it seem to be very magical, but it worked!

Replace ID with text in rails_admin associations

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

Ruby on Rails: How do I sum up these elements in my database?

I have a video_votes table with all the votes with a column called value set to 1 or -1. I want to sum up all the values of the video's votes and display that net vote count. First, how should I sum this up, and second, should I store this value in my video table? If so, how?
I would start with this until performance became an issue:
class Video < AR::Base
has_many :video_votes
def vote_sum
video_votes.sum(:value)
end
end
class VideoVote < AR::Base
belongs_to :video
validates_inclusion_of :value, :in => [-1,1]
end
Once performance became an issue and I wanted to cache the summed value I might do something like this:
class Video < AR::Base
has_many :video_votes
# Override vote_sum attribute to get the db count if not stored in the db yet.
# The alternative is that you could remove this method and have the field
# populated by a migration.
def vote_sum
read_attribute(:vote_sum) || video_votes.sum(:value)
end
end
class VideoVote < AR::Base
belongs_to :video
validates_inclusion_of :value, :in => [-1,1]
after_create :update_video_vote_sum
private
def update_video_vote_sum
video.update_attributes(:vote_sum => video.vote_sum + value)
end
end
Check out the AR documentation on "Overwriting default accessors" (scroll down a bit)
http://ar.rubyonrails.org/classes/ActiveRecord/Base.html
In your Video model:
def total_votes
self.votes.sum(:value)
end
So an example might be:
#video.total_votes
Use ActiveRecord's sum method.
VideoVote.sum('value')
You shouldn't store it in the same table. If you have other fields you want to summarize then create a "summary" table and periodically summarize the fields and store the values there. ActiveRecord's other calculation methods might be of interest in that case.
I'm to sum 2 fields on the level a model:
def update_sum_times
update_attribute(:sum_of_fields, calc_two_dates)
end
def calc_two_dates
date_one + date_two
end

Resources