Sudden no method error in Active Admin? - ruby-on-rails

I have activeadmin installed and working fine for a 'reviews' section of may app, allowing me to add individual reviews to various locations in which my business is based. I tried to add the identical set up but using a BusinessReviews model rather than Reviews (thus allowing me to add business reviews on the same basis)
Everything works fine until I go into active admin (log in and accessing the 'Business Reviews' panel is fine, until I try and actually add a business review. I then get the error:
NoMethodError in Admin::BusinessReviews#new
undefined method `business_profile_image' for #<BusinessReview:0x007f893fe853d0>
My model is as follows:
class BusinessReview < ActiveRecord::Base
belongs_to :location
has_many :images, :as => :referrer
accepts_nested_attributes_for :images, :allow_destroy => true
def thumbnail
if self.images.count > 0
self.images.last.avatar(:thumb)
else
nil
end
end
end
my_app/admin/business_review.rb is as follows:
ActiveAdmin.register BusinessReview do
index do
column :business_reviewer_name
column :business_review_content
column :business_reviewer_address
column :rating
column :location do |business_review|
business_review.location.name
end
column :business_profile_image do |business_review|
image_tag(business_review.business_profile_image) if business_review.business_profile_image.present?
end
actions
end
show do |business_review|
attributes_table do
row :business_reviewer_name
row :business_profile_image
row :business_review_content
row :business_reviewer_address
row :rating
row :location do
business_review.location.name
end
end
panel "Images" do
table_for business_review.images do
column {|img| img.currently_used }
column {|img| image_tag(img.avatar.url(:large)) }
end
end
active_admin_comments
end
permit_params [:id, :business_reviewer_name, :business_profile_image, :business_review_content, :business_reviewer_address, :rating, :location_id], images_attributes: [:id,:_destroy,:avatar,:usage_type, :currently_used]
form do |f|
f.inputs 'Details' do
f.input :business_reviewer_name
f.input :business_profile_image
f.input :business_review_content
f.input :business_reviewer_address
f.input :rating
f.input :location
end
f.inputs "images" do
f.has_many :images, :allow_destroy => true, :heading => 'Images', :new_record => true do |imgf|
imgf.input :currently_used
imgf.inputs "Attachment", :multipart => true do
imgf.input :avatar, :as => :file, :hint => imgf.object.avatar? \
? imgf.template.image_tag(imgf.object.avatar.url(:large))
: imgf.template.content_tag(:span, "no image yet")
end
end
end
f.actions
end
end
Relevant part of my schema:
create_table "business_reviews", force: true do |t|
t.text "business_reviewer_content"
t.string "business_reviewer_name"
t.string "business_reviewer_address"
t.float "rating"
t.string "profile_image"
t.datetime "created_at"
t.datetime "updated_at"
end
The routes appear to be there ok too?
batch_action_admin_business_reviews POST /admin/business_reviews/batch_action(.:format) admin/business_reviews#batch
_action
admin_business_reviews GET /admin/business_reviews(.:format) admin/business_reviews#index
POST /admin/business_reviews(.:format) admin/business_reviews#creat
e
new_admin_business_review GET /admin/business_reviews/new(.:format) admin/business_reviews#new
edit_admin_business_review GET /admin/business_reviews/:id/edit(.:format) admin/business_reviews#edit
admin_business_review GET /admin/business_reviews/:id(.:format) admin/business_reviews#show
PATCH /admin/business_reviews/:id(.:format) admin/business_reviews#updat
e
PUT /admin/business_reviews/:id(.:format) admin/business_reviews#updat
e
DELETE /admin/business_reviews/:id(.:format) admin/business_reviews#destr
oy
I just don't get it as the reviews one I set up works perfectly and is identical (apart from the not haveing business_ appended to it).

According to your schema there is no business_profile_image but just profile_image:
t.string "profile_image"
So either rename the column or use profile_image instead of business_profile_image.

Related

Rails 4.2.4 ActiveAdmin Globalize show one input only

Here I have a problem when using rails 4.2.4 + activeadmin 0.6.6 + rails-i18n 4.0.8 + globalize 4.0.3 + activeadmin-globalize 1.0.0 .
The problem I am facing is shown in the following image, it only show one input box for me:
In the contact table, I should have more variables as below:
db/migrate/XXXXXXXXX_create_contacts.rb
class CreateContacts < ActiveRecord::Migration
def up
create_table :contacts do |t|
t.string :url
t.boolean :publish, :default => false
t.integer :sequence
t.timestamps null: false
end
end
def down
drop_table :contacts
end
end
db/migrate/XXXXXXXXX_translate_for_contacts.rb
class TranslateForContact < ActiveRecord::Migration
def up
Contact.create_translation_table! :tool => :string, :content => :text
end
def down
Contact.drop_translation_table!
end
end
Contact table is originally generated using scaffold.
:url, :publish, :sequence are the variables common in all locales.
Only :tool and :content need to translate.
In app/models/contact.rb
class Contact < ActiveRecord::Base
active_admin_translates :tool, :content do
validates_presence_of :tool, :content
end
translates :tool, :content
end
In app/admin/contact.rb
ActiveAdmin.register Contact do
permit_params :url, :tool, :content, :publish, :sequence, translations_attributes: [:id, :locale, :tool, :content]
index do
translation_status
default_actions
end
form do |f|
f.translated_inputs "Translated fields", switch_locale: false do |t|
t.input :tool
t.input :content
end
f.actions
end
end
One more related thing, as I have also facing the "missing form_buffers" problem, I have edited the code in the activeadmin-globalize gem as following webpage:
https://github.com/maxime-carbonneau/activeadmin-globalize/commit/734f375152982ccde12e7810760a7ab82c8d4a20
but I am not sure if this edit will cause the problem.
Before I install and use activeadmin-globalize, I am sure there are the input boxes for :url, :publish, :sequence.
Do anyone have the solution or know what's happened? Thanks!
----------------Final Solution--------------------
As activeadmin-globalize is not maintained, most of it function not work normally. I recommend using another gem for it.
In the docs for the activeadmin-globalize gem, the author on Dec 9, 2014 warned users that he's not maintaining the gem anymore and to take it as you will. You may want to consider dropping the gem.
But, as activeadmin is concerned, I believe the reason your not seeing any other form inputs on your page is because you have haven't included them in your code below
# app/admin/contact.rb
...
form do |f|
f.translated_inputs "Translated fields", switch_locale: false do |t|
t.input :tool
t.input :content
end
f.actions
end
If you want to include them back in you will either need to just remove that entire block of code altogether and let activeadmin create the default form inputs for you or you can individually add your inputs back in
# app/admin/contact.rb
...
form do |f|
f.translated_inputs "Translated fields", switch_locale: false do |t|
t.input :url
t.input :tool
t.input :content
t.input :publish
...
end
f.actions
end

Rails user to user messages

I'm very new to rails so please be detailed in your responses. I'm building a web app that uses devise for authentication. The part that I'm stuck on right now is a user to user messaging system. The idea is that User A logs into the app and can visit user B's profile, and on User B's profile can click on a link that allows User A to compose a message to User B. Then User B can log into the app and visit the inbox where User A's message will be found.
I believe that I'm having trouble defining the sender and recipient roles here, right now I'm trying to display the form that users will compose their message in. Can anyone see what I'm doing wrong here? I get the following error. I've read that the thing to do is add the User_id field to the table, but I'm hoping to link this messages up using sender_id and recipient_id, which both equal user_id (e.g. User 1[sender] sends a message to User 2 [recipient]):
unknown attribute: user_id
def new
#message = current_user.messages.new recipient_id: params[:sender_id]
end
Additionally, for you rails experts or anyone that has done something similar to this, can you advise whether or not I'm going in the right direction, or offer any guidance? I'm sort of coding blind here and just trying to make it up as I go along. Any guidance would be hugely appreciated and save me a lot of time i'm sure. Code below:
Users Migration
class DeviseCreateUsers < ActiveRecord::Migration
def change
create_table(:users) do |t|
t.string :first_name
t.string :last_name
t.string :email, null: false, default: ""
t.string :encrypted_password, null: false, default: ""
t.string :reset_password_token
t.datetime :reset_password_sent_at
t.datetime :remember_created_at
t.integer :sign_in_count, default: 0, null: false
t.datetime :current_sign_in_at
t.datetime :last_sign_in_at
t.string :current_sign_in_ip
t.string :last_sign_in_ip
t.timestamps
end
add_index :users, :email, unique: true
add_index :users, :reset_password_token, unique: true
end
end
Messages Migration
class CreateMessages < ActiveRecord::Migration
def change
create_table :messages do |t|
t.string :content
t.integer :sender_id
t.integer :recipient_id
t.timestamps
end
end
end
schema.rb
ActiveRecord::Schema.define(version: 20140909174718) do
create_table "messages", force: true do |t|
t.string "content"
t.integer "sender_id"
t.integer "recipient_id"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "users", force: true do |t|
t.string "first_name"
t.string "last_name"
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip"
t.string "last_sign_in_ip"
t.datetime "created_at"
t.datetime "updated_at"
t.string "current_industry"
t.integer "years_in_current_industry"
t.string "hobbies"
end
add_index "users", ["email"], name: "index_users_on_email", unique: true
add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
end
routes.rb
Catalyst::Application.routes.draw do
devise_for :users, :controllers => { :registrations => "registrations" }
devise_scope :user do
get 'register', to: 'devise/registrations#new'
get 'login', to: 'devise/sessions#new', as: :login
get 'logout', to: 'devise/sessions#destroy', as: :logout
end
resources :users do
member do
get 'edit_profile'
end
resources :messages, only: [:new, :create]
end
resources :messages, only: [:index, :show, :destroy]
root to: "home#index"
match '/about', to: 'static_pages#about', via: 'get'
match '/contact', to: 'static_pages#contact', via: 'get'
match '/help', to: 'static_pages#help', via: 'get'
match '/legal', to: 'static_pages#legal', via: 'get'
end
users_controller
class UsersController < ApplicationController
before_filter :authenticate_user!
def index
#users = User.all
end
def show
#user = User.find(params[:id])
end
def new
end
def create
end
def edit
end
def update
#user = User.find(params[:id])
#user.update!(user_params)
redirect_to #user
end
def destroy
end
def edit_profile
#user = User.find(params[:id])
end
def user_params
params.require(:user).permit(:first_name, :last_name, :email, :password, :password_confirmation, :current_industry, :years_in_current_industry, :hobbies)
end
def sender
#user = User.find(params[:id])
end
def recipient
#user = User.find(params[:id])
end
end
messages_controller
class MessagesController < ApplicationController
before_action :set_recipient
def new
#message = Message.new
#recipient = User.find(params[:user_id])
end
def create
#message = Message.new message_params
if #message.save
flash[:success] = "Your message has been sent!"
redirect_to user_messages_path
else
flash[:failure] = "Please try again."
redirect_to users_path
end
end
private
def message_params
params.require(:message).permit(:content, :sender_id, :recipient_id)
end
end
user.rb
class User < ActiveRecord::Base
has_many :from_messages, class_name: 'Message', :foreign_key => "sender_id"
has_many :to_messages, class_name: 'Message', :foreign_key => "recipient_id"
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
attr_accessible :first_name, :last_name, :email, :password, :password_confirmation, :remember_me, :current_industry, :years_in_current_industry, :hobbies
end
message.rb
class Message < ActiveRecord::Base
belongs_to :sender, class_name: "User"
belongs_to :recipient, class_name: "User"
validates :content, presence: true, length: { maximum: 500 }
validates :sender_id, presence: true
validates :recipient_id, presence: true
end
messages/index.html.erb
<h2>Inbox</h2>
messages/new.html.erb
<h1>Create Message</h1>
<%= form_for [#recipient, #message] do |f| %>
<%= f.hidden_field :recipient_id, value: #recipient.id %>
<%= f.label "Enter your message below" %><br />
<%= f.text_area :content %>
<%= f.submit "Send" %>
<% end %>
rake routes
user_messages POST /users/:user_id/messages(.:format) messages#create
new_user_message GET /users/:user_id/messages/new(.:format) messages#new
users GET /users(.:format) users#index
POST /users(.:format) users#create
new_user GET /users/new(.:format) users#new
edit_user GET /users/:id/edit(.:format) users#edit
user GET /users/:id(.:format) users#show
PATCH /users/:id(.:format) users#update
PUT /users/:id(.:format) users#update
DELETE /users/:id(.:format) users#destroy
messages GET /messages(.:format) messages#index
message GET /messages/:id(.:format) messages#show
DELETE /messages/:id(.:format) messages#destroy
Models
#app/models/user.rb
class User < ActiveRecord::Base
has_many :messages, class_name: "Message", foreign_key: "recipient_id"
has_many :sent_messages, class_name: "Message", foreign_key: "sender_id"
end
#app/models/message.rb
class Message < ActiveRecord::Base
belongs_to :recipient, class_name: "User", foreign_key: "recipient_id"
belongs_to :sender, class_name: "User", foreign_key: "sender_id"
scope :unread, -> { where read: false }
end
This should give you the ability to create messages which "belong" to a user (IE the recipient), and then you can associate a "sender" profile to those messages.
--
Controllers
This will give you the ability to call the following:
#app/controllers/messages_controller.rb
class MessagesController < ApplicationController
before_action :set_recipient, only: [:new, :create]
def new
#message = current_user.sent_messages.new
end
def create
#message = current_user.sent_messages.new message_params
#message.recipient_id = #recipient.id
#message.save
end
def index
#messages = current_user.messages
end
def destroy
#message = current_user.messages.destroy params[:id]
end
def show
#message = current_user.messages.find params[:id]
end
private
def message_params
params.require(:message).permit(:content, :recipient_id, :sender_id)
end
def set_recipient
#recipient = User.find params[:user_id]
end
end
--
Routes
#config/routes.rb
devise_for :users, path: "", controllers: { :registrations => "registrations" }, path_names: {sign_up: "register", sign_in: "login", sign_out: "logout"}
resources :users do
get :profile
resources :messages, only: [:new, :create] #-> domain.com/users/:user_id/messages/new
end
resources :messages, only: [:index, :show, :destroy] #-> domain.com/messages/:id
--
Views
This will give you the ability to use the following links:
#app/views/users/show.html.erb (user to send message to)
<%= link_to "Send Message", user_messages_path(#user.id) %>
#app/views/messages/new.html.erb
<%= form_for [#recipient, #user] do |f| %>
<%= f.text_field :content %>
<%= f.submit %>
<% end %>
#app/views/messages/index.html.erb
<h2>Inbox</h2>
<% #messages.each do |message| %>
<%= message.content %>
<% end %>
--
Fix
I've read that the thing to do is add the User_id field to the table,
but I'm hoping to link this messages up using sender_id and
recipient_id, which both equal user_id (e.g. User 1[sender] sends a
message to User 2 [recipient])
You don't need to add user_id to your table. user_id is merely a foreign_key, which you've overridden in your models.
All you need to do is set the recipient_id and sender_id, which we're doing in the create method:
def create
#message = current_user.message.new message_params
#message.recipient_id = #recipient.id
#message.save
end
You've done some very clever things here.
Firstly, you have implicitly set the sender_id foreign key by calling current_user.messages. If you had called Message.new, it would have been a completely different story (having to set sender_id)
Secondly, because you're using nested routes, you'll be able to use the #recipient variable you've set in the before_action method to give us the id for the recipient_id.
This should work for you. You won't need to use inverse_of unless you are trying to access "parent" model data in a child / nested model.
Recommendations
What you're doing is completely valid
The core trick is to make sure your Message model is completely separate & independent to your User. This is achieved with your setup, allowing you to create the various objects that you require.
The other aspect you need to consider is how you're going to ensure you're able to provide the users with the ability to have "threaded" messages. You'll achieve this using one of the hierarchy gems, either Ancestry or Closure_Tree
Adding this functionality will be a little more in-depth. I can provide information if you require (just leave a comment)
Threading
The hierarchy gems are actually relatively simple to use.
The trick to "treading" your messages is to use one of these gems (either Ancestry or Closure_Tree), as they provide you with "methods" which you can call on your items. They work by creating several columns in your database, populating them as you save / create the objects you desire
The "threading" issue is a big one, as without the "hierarchy" gems, you won't be able to call the "child" objects of the record you want, thus preventing the threading from occurring. Here's a good Railscast on how to achieve it:
The trick with this is to use something called "recursion"
Recursion is where you create an "indefinite" loop, so far as how "recursive" the data is. EG if you have an object with children, you'll have to cycle through the children, and then the children of those children, recursively until you reach the point of showing all the data:
Recursion is the process of repeating items in a self-similar way. For
instance, when the surfaces of two mirrors are exactly parallel with
each other, the nested images that occur are a form of infinite
recursion.
As such, here's how you to it:
Make sure you save your objects with the correct parents
To display the "threaded" conversation, loop through those parents
Use recursion to loop through their children
We use the ancestry gem, which stores the hierarchy slightly differently to the closure_tree gem we've since discovered (intend to use the closure tree gem soon).
You firstly have to therefore save any hierarchy yourself:
This will allow you to save the various "parents" for that object. This means that when you load the object, and wish to cycle through its descendent, you'll be able to use the Ancestry object methods:
Which means you'll be able to use the following:
#app/views/comments/index.html.erb
<%= render partial: "comments", locals: { collection: #comments } %>
#app/comments/_comments.html.erb
<% collection.arrange.each do |comment, sub_item| %>
<%= link_to comment.title, comment_path(comment) %>
<% if category.has_children? %>
<%= render partial: "category", locals: { collection: category.children } %>
<% end %>
<% end %>
To solve the error you have, try to set :inverse_of attribute of has_many and belongs_to statements in your model classes. You can end up having two has_many - one per each belongs_to reverse:
user.rb:
has_many :from_messages, :class_name => 'Message', :foreign_key => "sender_id", :inverse_of => :sender
has_many :to_messages, :class_name => 'Message', :foreign_key => "to_id", :inverse_of => :recipient
message.rb:
belongs_to :sender, :class_name => 'User', :inverse_of => :from_messages
belongs_to :recipient, :class_name => 'User',:inverse_of => :to_messages
Overall I think your approach is a good starting point for a messaging system. You can try to post your code to https://codereview.stackexchange.com/ for a detailed review.

Geocoder with One to Many realtionship Ruby on Rails

I have two models in my Rails app which form a one_to_many relationship. The first model, store, represents a brick and mortar store and has latitude and longitude columns which are being geocoded correctly using the 'geocoder' gem and an address column. The store has_many products. The product has_one store. I would like to return the index of products based on proximity to an address which the user inputs in the search form. Here are the relevant parts of my code as well as my attempt at implementing the search:
in schema.rb:
create_table "products", force: true do |t|
t.string "title"
...
t.integer "store_id"
end
create_table "stores", force: true do |t|
...
t.string "business_address"
t.float "latitude"
t.float "longitude"
end
in store.rb
class Store < ActiveRecord::Base
has_many :products
geocoded_by :business_address
after_validation :geocode, :if => :business_address_changed?
end
in product.rb
class Offer < ActiveRecord::Base
belongs_to :store
end
in views/products/search.html.erb
...
<%= form_tag products_path, :method => 'get' do %>
<p>
Find products near<br />
<%= text_field_tag :custom_address, params[:custom_address] %><br />
</p>
<p>
<%= submit_tag "Search", :name => nil %>
</p>
<% end %>
in products_controller.rb
def index
#products = Store.near(params[:custom_address], 100, order: :distance, :select => "products.*")
end
The above index method generates a
ActiveRecord::StatementInvalid in Products#index
error
I am not sure how to continue. Obviously there is a problem with the way I am using the near method and :select but I can't wrap my head around it. How can I return the products sorted by distance?
I am using MySQL as the database adapter; I have heard of issues due to a lack of trig functions with SQLite.
I got my code working properly by using the following:
I added an attr_accessor in the Product model:
class Product < ActiveRecord::Base
belongs_to :store
attr_accessor :distance_to_user
end
And I changed the index method:
def index
#products = []
if params[:custom_address]
geocoded_stores = (Stores.near(params[:custom_address], 100,))
geocoded_stores.each do |s|
s.products.each do |product|
product.distance_to_user = s.distance
#products << product
end
end
else
#products = Product.all
end
end

specify columns from has many through association Rails

I have three models.
User
has_many :boards through => :celebrations
has_many :celebrations, :dependent => :destroy
Board
has_many :celebrations, :dependent => :destroy
has_many :users, :through => :celebrations do
def by_role(role)
find(:all, :conditions => ["celebrations.role = ?", role])
end
end
Celebration
:belongs_to :user
:belongs_to :board
Celebration Table
create_table :celebrations do |t|
t.column :board_id, :int, :null => false
t.column :user_id, :int, :null => false
t.column :role, :string, :null => false
t.column :token, :string
t.column :accepted, :boolean, :default => false
t.timestamps
In the controller:
#board = Board.find(session[:board_id])
#friends = #board.users.by_role("FRIEND")
In the view:
<% for friend in #friends do %>
<%= friend.name %>
<%= friend.email %>
However when I do the following:
<% friend.celebration.accepted %>
I get the following error:
undefined method `celebration' for #<User:0x104788c00>
How can I access the column 'accepted' in the celebrations table returned along with the record using the model extension "by_role(role)".
Thank you for your help in advance.
You can eager load the celebrations like this:
Board model:
Board
has_many :celebrations, :dependent => :destroy
has_many :users, :through => :celebrations do
def by_role(role)
find(:all, :conditions => ["celebrations.role = ?", role], :include => :celebrations)
end
end
With :include you will have one more hit:
Celebration Load (0.2ms) SELECT celebrations.* FROM celebrations WHERE (celebrations.user_id IN (5,6))
that loads the celebrations data for users.
This will avoid in this particular case two hits that would be needed to retrieve celebrations for each user. If you have 10 users you will end with one hit instead of 10.
Eager loading loads all the data you will need to cycle through in association with one query instead of n queries.
The problem remains for the accepted data because you will have an array of celebrations due to the has_many relationship with user.
You can use something like this:
<% friend.celebrations.map{|celeb| celeb.accepted }.join(",") %>

Rails money gem and form builder

I'm having an issue with the forms and the money gem.
This is my problem:
I create a record which has an "amount" field (mapped to money object). Let's say I enter 10 (dollars).
The money gem converts it to 1000 (cents)
I edit the same record and the form pre-populates the amount field as 1000
If I save the record without changing anything, it will convert the 1000 (dollars) to 100000 (cents)
How do I make it display the pre-populated amount in dollars instead of cents?
Edit:
I tried editing the _form.html like this:
= f.text_field(:amount, :to_money)
and I get this error:
undefined method `merge' for :to_money:Symbol
Given a migration as follows:
class CreateItems < ActiveRecord::Migration
def self.up
create_table :items do |t|
t.integer :cents
t.string :currency
t.timestamps
end
end
def self.down
drop_table :items
end
end
And a model as follows:
class Item < ActiveRecord::Base
composed_of :amount,
:class_name => "Money",
:mapping => [%w(cents cents), %w(currency currency_as_string)],
:constructor => Proc.new { |cents, currency| Money.new(cents || 0, currency || Money.default_currency) },
:converter => Proc.new { |value| value.respond_to?(:to_money) ? value.to_money : raise(ArgumentError, "Can't conver #{value.class} to Money") }
end
Then this form code should work perfectly (I just tested under Rails 3.0.3), properly displaying and saving the dollar amount every time you save/edit. (This is using the default scaffold update/create methods).
<%= form_for(#item) do |f| %>
<div class="field">
<%= f.label :amount %><br />
<%= f.text_field :amount %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
You can now edit monetized fields directly (money-rails 1.3.0):
# add migration
add_column :products, :price, :price_cents
# set monetize for this field inside the model
class Product
monetize :price_cents
end
# inside form use .price instead of .price_cents method
f.text_field :price
See https://stackoverflow.com/a/30763084/46039
If you have multiple money fields in your table and you can't name them all "cents".
class CreateItems < ActiveRecord::Migration
def self.up
create_table :items do |t|
t.integer :purchase_price_cents
t.string :currency
t.timestamps
end
end
def self.down
drop_table :items
end
end
which would change your model to
class Item < ActiveRecord::Base
composed_of :purchase_price,
:class_name => "Money",
:mapping => [%w(purchase_price_cents cents), %w(currency currency_as_string)],
:constructor => Proc.new { |purchase_price_cents, currency| Money.new(purchase_price_cents || 0, currency || Money.default_currency) },
:converter => Proc.new { |value| value.respond_to?(:to_money) ? value.to_money : raise(ArgumentError, "Can't convert #{value.class} to Money") }
end
monetizing and the simple form, the steps as follows:
Migration
add_monetize :table, :amount
Model with validation
monetize :amount_cents, allow_nil: true, numericality: {greater_than: 0}
Controller permit params (dont use amount_cents here)
params.require(:model).permit(:amount)
simple form input
when it's saved it will be saved in cents in amount_cents column in db

Resources