rails 4 gem 'mongoid_slug' unable to search by id - ruby-on-rails

I just installed the gem 'mongoid_slug', here is the model:
class Book
include Mongoid::Document
include Mongoid::Timestamps
include Mongoid::Slug
field :_id, type: String, slug_id_strategy: lambda {|id| id.start_with?('....')}
field :name, type: String
slug :name,
...
end
In the controller I have a function call get_book that I call before edit, show etc
Of course it is not working, I also tried find_by_slug.
Error Document not found for class Book with attributes {:id=>"try-new-book"}.
Request info
Request parameters
{"action"=>"show", "controller"=>"startups", "id"=>"try-new-book"}
def get_book
#book = Book.find_by(id: params[:id])
end
Thank you

According to docs it should works just:
Book.find params[:id]
Updated
I answered the same question here. So in short: change id.start_with?('....') to something like id =~ /^[[:alnum:]]+$/

Related

Implementing elasticsearch index update in ruby on rails application

I am creating a rails application with integration to elasticsearch for fulltext search. I have the search working for a model, however when another part of the app does an attribute_update on it, I get below error:
Elasticsearch::Transport::Transport::Errors::BadRequest ([400] {"error":"no handler found for uri [/cards/_doc/123/_update] and method [POST]"}):
I tried to add a call to update_document in the model, however, I still get the same error as above.
class Card < ApplicationRecord
include Searchable
validates :attr1, uniqueness: true
after_update :my_es_update
def my_es_update
self.__elasticsearch__.update_document
end
def self.es_full_search
response = Card.__elasticsearch__.search(
query: {
match_all: {}
},
size: 150
).results
#cards = response.results
end
Update call:
def pin
#card = Card.find(params[:id])
#card.update_attribute("pinned", true)
redirect_back(fallback_location: root_path)
end
What would be the right way to update the index in ES upon update to persistence layer?
Edit:
I have the Elasticsearch::Model::Callbacks module included in my model, per the documentation it should take care of updates...I am not sure what part of the setup I am missing here.
module Searchable
extend ActiveSupport::Concern
included do
include Elasticsearch::Model
include Elasticsearch::Model::Callbacks
mapping do
indexes :name, type: :text
indexes :type, type: :text
indexes :size, type: :text
end
end
end
Update2:
I am using ES vsn 8.5.3 and the 2 below gems in my Gemfile for communicating with it:
gem 'elasticsearch'
gem 'elasticsearch-model', '~> 7.2.1'

Mongoid in ruby-on-rails

I am using the Mongoid gem according to this https://docs.mongodb.com/mongoid/current/tutorials/getting-started-rails/
But now i want to make a usermodel with few attributes
How do i update these attributes in rails controller
puts"saving data"
Mongo::Logger.logger.level = :: Logger:: FATAL
client - Mongo::Client.new(['127.0.0.1:27017' ], :database => 'mydb')
doc ={:_id=>1,:token=> oauth_token, token_secret-> oauth_token_secret}
client[:UserTable].insert_one doc
client.close
puts"saved data"
The above code directly works with mongodb I want to do this same job via model
First you should create the class for mongoid
class User
include Mongoid::Document
store_in collection: 'UserTable'
field :token, type: String
field :token_auth, type: String
end
and later you can use in your controller sentences like:
user = User.find(params[:id])
user.update_attributes(update_params)

Embeds_many child property not persisted when saving parent

I've been looking for some days without finding the exact answer to my problem which is as simple as that : I have a simple model, with books and authors. A book embeds many authors, and an author is embedded in book. But whenever I'm saving a new book, the author array is not persisted.
What I have is an angular 7 application, calling a ROR API. My Rails versions is 5.2.2. I am using mongoid 7.0 for persistence.
My API was generated with rails g scaffold, and with the --api and --skip-active-record flags.
I first had a problem with the mapping of my properties. My Angular APP sends JSON in lowerCamelCase, when Rails awaits form lower_snake_case vars. I managed to bypass this problem by adding a middleware (correct me if I'm wrong on this one) in my initializers which converts camelCase to snake_case.
# Transform JSON request param keys from JSON-conventional camelCase to
# Rails-conventional snake_case:
ActionDispatch::Request.parameter_parsers[:json] = -> (raw_post) {
# Modified from action_dispatch/http/parameters.rb
data = ActiveSupport::JSON.decode(raw_post)
data = {:_json => data} unless data.is_a?(Hash)
# Transform camelCase param keys to snake_case:
data.deep_transform_keys!(&:underscore)
}
From what I found looking for my problem, it could have been a problem with strong params, so I tried to get awat with this in my book_params
def book_params
#params.fetch(:book, {})
params.require(:book).permit(:title, :release_date, authors_attributes: [:name, :last_name, :birth_date])
end
These are my model :
class Person
include Mongoid::Document
field :last_name, type: String
field :first_name, type: String
field :birth_date, type: Date
end
class Author < Person
include Mongoid::Document
embedded_in :book
end
class Book
include Mongoid::Document
field :title, type: String
field :release_date, type: Date
embeds_many :authors
accepts_nested_attributes_for :authors
end
And this is POST in my book controller (generated with Rails)
# POST /books
def create
#book = Book.new(book_params)
if #book.save
render json: #book, status: :created, location: #book
else
render json: #book.errors, status: :unprocessable_entity
end
end
And here are exemple of a body sent, received and how it is processed by Rails :
Request sent by angular app
Request received and processed by Rails
We can see in the book object
"book"=>{"title"=>"azerty", "release_date"=>"2019-01-21T16:10:19.515Z"}}
That the authors have disappeared, though they were present in the request received by the server.
My question is then : what is the solution to this, or at least what am I missing ? Doesn't Mongoid automatically save children when using embedded documents and accepts_nested_attributes_for ? Should I manually save the children each time a parent is saved in my controller ?
Thanks in advance for helping me
You have to use nested attributes to save children records
Add following line in book model
accepts_nested_attributes_for :authors
And pass authors parameters in author_attributes, for exa:
{title: 'test', release_date: '', author_attributes: [{first_name: '', other_attributes of author}, {first_name: '', , other_attributes of author}]}
for more details please check Mongoid: Nested attributes
Pass perameters in this format
{"title"=>"test", "release_date"=>"2019-01-22", "book"=>{"title"=>"test", "release_date"=>"2019-01-22", "authors_attributes"=>[{"first_name"=>"test name", "last_name"=>"test", "birth_date"=>"2019-01-22T09:43:39.698Z"}]}}
Permit book params
def book_params
params.require(:book).premit(:first_name, :last_name, authors_attributes: %i[first_name last_name birth_date])
end

How to create index of an instance method in elasticsearch-rails?

What I want to do
https://github.com/elastic/elasticsearch-rails/tree/master/elasticsearch-model
Using this gem, I wanna create indexes of User model, including output of method named full_name. User has columns of id, first_name, last_name.
class User
...
def full_name
first_name + last_name
end
...
end
What I did
module UserSearchable
extend ActiveSupport::Concern
included do
include Searchable
settings index: {
...
}
mappings do
indexes :id, type: :integer
indexes :first_name, type: text
indexes :last_name, type: text
indexes :full_name, type: text, as: 'full_name'
end
def as_indexed_json(options={})
as_json(
methods: [:full_name]
)
end
end
end
I referred to this question.
Index the results of a method in ElasticSearch (Tire + ActiveRecord)
But this doesn't work, ending up with not containing full_name index in the response.
I'm new to elasticsearch and elasticsearch-rails.
How can I fix this?
Sorry, I just forgot to reload changes in the code!
And It works without as: 'full_name' in current version of the gem.

Custom Typecaster with ActiveAttr Rails Gem

I would like to create a custom Typecaster for the ActiveAttr Gem.
I have a Package class:
class Package
include ActiveAttr::Model
attribute :quantity, :type => Integer
attribute :detail
attribute :type
attribute :order
def shipping
end
end
and I have Order class
class Order
include ActiveAttr::Model
attribute :id, :type => Integer
def test
end
end
In the Package class I want to use attribute :order, :type => OrderTypecaster because when I create a new package (p = Package.new(params['package']) I would like to set the Order id attribute automatically.
Is this possible?
I'm using Rails 3.2.13
Tks!
I found a way to solve my problem without create a custom Typecaster.
In Package class I wrote two simple methods:
def order=(value)
#order = Order.new(value)
end
def order
#order ||= Order.new
end
Now when I call Package.new(params['package']) the order id is automatically setted.
I don't know if this is the best solution but works well, any better solution is welcome. :)
Tks guys!

Resources