How can I add values to string field in database from multiple select.
I have field in database:
t.string "types"
and view:
<%= f.select :order, [["One", 1], ["Two", 2], ["Three", 3]], {}, { :class => 'form-control', :multiple => true } %>
Maybe serialize or json is goot idea? Is it possible save and simple way read this?
You can use rails serialize on the column:
serialize :order, Hash
Or for JSON (depending what you want to do with it):
serialize :order, JSON
However, the columns needs to be of type 'text' not 'string' for serialize to work, so be sure to create a migration to change the column type.
rails g migration change_order_type_in_table_name
class ChangeOrderTypeInTableName < ActiveRecord::Migration
def up
change_column :my_table, :order, :text
end
def down
change_column :my_table, :order, :string
end
end
You can pass a class to serialize:
class User < ActiveRecord::Base
serialize :order, Array
end
The above ensures that order as an Array:
User.new
#=> #<User id: nil, order: [], created_at: nil, updated_at: nil>
Note that you might have to convert existing fields if the types don't match.
Related
I am trying to query a datatype in my jsonb column. When I query with standard SQL, the response is empty. I was using this as a reference.
My data: id: "f0242deb-fef5-4221-b4eb-68610d355a06", metadata: {"classification"=>"unclassified"}
My controller query: Transaction.where('metadata #> ?', {classification: 'unclassified'}.to_json)
I get this as a response Transaction Load (39.0ms) SELECT "transactions".* FROM "transactions" WHERE (metadata #> '{"classification":"unclassified"}') => []
I would expect the response to include the above dataset since the classification matches. Where am I going wrong?
Schema and models for reference.
schema.rb
create_table "transactions", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
t.jsonb "metadata", default: "{}", null: false
t.index ["metadata"], name: "index_transactions_on_metadata", using: :gin
end
transaction.rb
class Transaction < ApplicationRecord
require 'json'
include ActiveModel::Serialization
serialize :metadata
store_accessor :metadata, :classification, :amount, :merchant, :category
validates :transaction_date, :classification, :amount, :merchant, :category, presence: true
end
i think the problem is json serialization, it looks like this will force convert the input json data, take a look (on my project):
> Event.create(payload: {question: "jsonb index", answer: "json serialize"})
> ... ["payload", "\"---\\n:question: jsonb index\\n:answer: json serialize\\n\""]
in database, that payload will be saved as: "---\n:question: jsonb index\n:answer: json serialize\n", and the jsonb query can not find it.
Now change the serializer
#require 'json'
#include ActiveModel::Serialization
serialize :payload, HashSerializer
store_accessor :payload, :question, :answer
the payload will be saved as {"answer": "serialize", "question": "jsonb index"} and jsonb query can find it.
Of course it also works if i remove serialize
Keep in mind that database adapters handle certain serialization tasks for you. For instance: json and jsonb types in PostgreSQL will be converted between JSON object/array syntax and Ruby Hash or Array objects transparently. There is no need to use #serialize in this case.
Hi I have generated a migration to add_column rails g migration AddColumnToEmployees
class AddColumnToEmployees < ActiveRecord::Migration
def change
add_column :employees, :role, "enum('SUPER-ADMIN', 'HR','ADMIN','INVENTORY','EMPLOYEE')", :default => 'EMPLOYEE'
end
end
run rake db:migrate
Now I want to access role in my view for this I have written this:
<%=f.select :role, :collection => Employee.roles %>
But its not accessing it. It gives error
undefined method 'roles' for #<Class:0xc2acd88>
Please guide how to solve this. Thanks in advance!
I was under the impression you represented the enum as an integer in the DB, so your migration should be:
class AddColumnToEmployees < ActiveRecord::Migration
def change
# Assuming Employee is the first value in your enum list
add_column :employees, :role, :integer, default: 0
end
end
and your select should be:
<%= f.select :role, :collection => Employee.roles.keys.to_a %>
See Saving enum from select in Rails 4.1
Your model:
class Employee
enum role: [:employee, :inventory, :admin, :hr, :superadmin]
end
Rails does automatically provide you with all potential values through a class method with the pluralized attribute name.
your migration is fine. after your migration to access it in view like that
<%=f.select :role, :collection => Employee.roles.keys.to_a %>
and define enum field in model employee.rb
enum role: {
super_admin: 1,
hr: 2,
admin: 3,
inventory: 4,
employee: 5
}
convert in enum role of model into hash. and assign the value. and run it.i will try my best hope it will help you!!
Try following code, I hope this will help you.
in AddColumnToEmployees migration file.
class AddColumnToEmployees < ActiveRecord::Migration
def change
add_column :employees, :role, :integer, default: 0
end
end
in Employee Model.
class Employee
enum role: [ :super_admin, :hr, :admin, :inventory, :employee ]
end
and finally in view file.
<%= f.select :role, options_for_select(Employee.roles.collect { |e| [e[0].humanize, e[0]] }) %>
I want to store multiple values (integers) in my database field. For that i use
serialize :subtype, Array
whenever i submit a form i get this parameters for subtype
"subtype"=>["",
"1",
"3"],
Now i try to save this values into my database. So i try to do something like that
#request.subtype << params[:subtype][1] << params[:subtype][2]
#request.save
Of course it doesn't work. How can i do that? How to store these values.
This is my migration:
create_table :requests do |t|
....
t.integer :subtype
....
t.timestamps null: false
end
In my form i have:
<%= f.grouped_collection_select :subtype,
RequestType.order(:typeName), :RequestSubTypes, :typeName, :id, :subTypeName,
{include_blank:false},{:class => "subTypes", multiple: true } %>
Serialize field can't be integer type.So change it to text type
Run this migration
rails g migration add_subtype_to_requests subtype:text
class Migration000000
def change
add_column :requests, :subtype, :text
end
end
Then this should work for you
#request.save
EDIT
In your controller allow subtype array
def request_params
params.require(:request).permit(:field1, :field2, :subtype => [])
end
You don't need to append to the column, just do this:
#request.subtype = params[:subtype].reject { |st| st.blank? }
#request.save
As sub_type is an array, this is all you need to do.
This is the initial migration where I set a default value:
class CreateMove < ActiveRecord::Migration
def change
create_table :moves do |t|
...
t.text :move_types, :null => false, :default => [0]
...
end
end
end
And this is the model:
class Move < ActiveRecord::Base
serialize :move_types, Array
end
Now, when I call Move.new, I get the following:
=> #<Move id: nil, move_types: "'---\n- 0\n'">
But what I should be getting is
=> #<Move id: nil, move_types: [0]>
In fact, when I create a Move with Move.create(move_types: [0]) and I fetch that move, this is what is returned!
This was a bug in Rails. It is now fixed in Rails 4.
I recently added a :title column using Rails migration:
class AddTitleToMicroposts < ActiveRecord::Migration
def change
add_column :microposts, :title, :string
end
end
I noticed that it appear at the end when I do user.microposts: in the console:
=> [#<Micropost id: 1, content: "test", user_id: 1, created_at: "2012-01-25 15:34:30", updated_at: "2012-01-25 15:34:30", title: nil>]
Is there any way of arranging the order of the title columns? Say, placing it right before the :content column?
There is an :after option to insert the columns (no :before option unfortunately)
class AddTitleToMicroposts < ActiveRecord::Migration
def change
add_column :microposts, :title, :string, :after => :content
end
end
Rearrange them in the schema and do rake db:schema: load