MySQL with rails - mysql

I have to pass all the data saved in "first" table to "first_archives" table with the help of queries only. I used the query in the controller of "first" under 'destroy' such that it is selecting the id from "first" and inserting into archive table.
The code as follows:
class FirstsController < ApplicationController
def destroy
#first = First.find(params[:id])
if #first.destroy
cd = First_archive.new :first_id =>"First.find :all, :conditions => { :id => #id }"
cd.save
respond_to do |format|
format.html { redirect_to(firsts_url) }
format.xml { head :ok }
end
end
Please help for the doubts for two things:
* Is the syntax used is correct.
* What we have to write in first_archive table.
Thank you

I have solved it by:
x = X.find(params[:id])
archive = XArchive.new
archive.x_id = X.id
archive.x_name = x.x_name
archive.start_date = x.start_date
archive.end_date = x.end_date
archive.created_at = x.created_at
archive.updated_at = x.updated_at
archive.save
x.destroy
take care

Related

Include parent attributes when searching via query

I have a User Model that has_many Job Applications.
Everything works great, but when I try to search Job Applications by the User's first_name I get the error below.
Error
SQLite3::SQLException: no such column: first_name: SELECT "job_applications"
From my understanding, I need to include the User attributes in the Job Application query.
How can I accomplish this?
View (job application)
<%= form_for :search, :html => {:method => :get, :id => 'search'} do |f| %>
<%= text_field_tag :terms, params[:terms], :type => 'search' %>
<% end %>
Controller (job application)
def index
#job = Job.find(params[:job_id])
#job_applications = #job.job_applications.search(params[:terms])
end
Model (job application)
def self.search(terms)
terms ||= ""
conditions = terms.split(" ").map do |term|
term = term.strip.gsub("'","''")
### I am having an issue here...
### how do i include the user attributes in this query
"first_name like '%#{term}%'"
end
where(conditions.join " OR ")
end
You have to join job_applications table with users table.
# job_applications.rb
def self.search(terms)
terms ||= ""
conditions = terms.split(" ").map do |term|
term = term.strip.gsub("'","''")
"users.first_name like :term"
end
joins(:user).where(conditions.join " OR ")
end
Avoid passing raw user's inputs into your queries directly to avoid sql injection. Use rails' built-in filters or sanitize it yourself.
def self.search(terms)
terms ||= ""
term_args = []
conditions = terms.split(" ").map do |term|
term = term.strip.gsub("'","''")
term_args << "%#{term}%"
"users.first_name like ?"
end
joins(:user).where(conditions.join(' OR '), term_args)
end

Trouble defining finder method in my application

I’m using Rails 4.2.3 and MySQL 5.5.37. I want to write a finder method for my model, so I have written this (./app/models/user_object.rb):
class UserObject < ActiveRecord::Base
validates :day, :presence => true
validates_numericality_of :total
validates :object, :presence => true
def find_total_by_user_object_and_year
UserObject.sum(:total, :conditions => ['user_id = ?', params[:user_id], 'object = ?', params[:object], 'year(day) = ?', params[:year]])
end
end
However, when I attempt to invoke the method within a controller like so
#my_total = UserObject.find_total_by_user_object_and_year(session["user_id"], 3, #year)
I get the following error
undefined method `find_total_by_user_object_and_year' for #<Class:0x007fb7551514e0>
What is the right way to define my finder method?
Use self.method to define class method:
def self.find_total_by_user_object_and_year
sum(:total, :conditions => ['user_id = ?', params[:user_id], 'object = ?', params[:object], 'year(day) = ?', params[:year]])
end
In this case UserObject inside class method definition is redundant, besause it is same as self. Now you can write:
UserObject.find_total_by_user_object_and_year(params)

How can I save a unique string by incrementing it in rails?

How can I save a unique string to my database and if the value exists increment it.
The behaviour I'm after is similar to when you save a file e.g. foo.txt, foo1.txt
I do NOT want to return a 'not unique value' error message.
class Person < ActiveRecord::Base
attr_accessible :name
end
Person.create(:name => 'Dave') # => 'Dave'
Person.create(:name => 'Dave') # => 'Dave1'
Person.create(:name => 'Dave') # => 'Dave2'
I'm using ruby, rails and mysql
you don't need to set validation uniqueness to your model . You can use something like this:
class Person < ActiveRecord::Base
attr_accessible :name
before_create :check_and_increment
private
def check_and_increment
if Person.exists? name: self.name
similar_persons = get_all_with_same_name self.name
next_num = similar_persons.max_by{|m| m.scan(/\d+/)}.scan(/\d+/).first.nil? ? 1 : similar_persons.max_by{|m| m.scan(/\d+/)}.scan(/\d+/).first.to_i + 1
self.name = "#{self.name}#{next_num}"
else
true
end
end
def get_all_with_same_name name
where("name LIKE ?", 'name%')
end
end
This is simple idea for your problem. Need to be carefull with persons like Anna and Annastasia, for example . These persons has different names but their names are overlap.
Hope this will help you .
I could not find any rails or mysql features to do this so I created the follow 3 methods and
def unique_name(name)
if Person.exists?(:name => name)
generate_unique_name(name)
else
name
end
end
def similar_names(name)
Person.where("name LIKE ?", "#{name}%").pluck(:name)
end
def generate_unique_name(name)
number = similar_names(name).map{ |a| a.scan(/\d+$/).max.to_i }.compact.max.to_i + 1
"#{name} #{number}"
end
...
Person.create(:name => unique_name('Dave'))

Rails 4 and Mongoid: Retrieving embedded document as json

I want to retrieve all the embedded documents of a document to return as a "list" of json elements.
I have documents as follows:
class Parent
include Mongoid::Document
field :name, :type => String
embeds_many :kids
class Kid
include Mongoid::Document
field :kidname, :type => String
embedded_in :parent, :inverse_of => :kids
I have defined two routes
get 'parents/:kidname' => 'parents#getparents'
where getparents is defined as
#retval = Parent.where("kids.kidname" => params[:kidname])
respond_to do |format|
format.html # index.html.erb
format.json { render json: #retval}
end
This gives me the correct output, i.e., the parent whose kid's name is params[:kidname]
However when I try to do the reverse, i.e., retrieve the list of all kids whose parent's name is params[:name], that doesn't work! The route is
get 'kids/:name' => 'parents#getkids'
and getkids is defined as
def getkids
#parent = Parent.where("name" => params[:name])
#kids = #parent.kids
respond_to do |format|
format.html # index.html.erb
format.json { render json: #kids}
end
end
What am I doing wrong? Does it matter where getkids is defined .. I defined it in parents_controller, should it be in kids_controller? Please help!
Thanks.
if you re not getting the results or getting some error change this line #parent = Parent.where("name" => params[:name]) to #parent = Parent.where("name" => params[:name]).first

Ruby on Rails joins models for json output

I'm trying to build a JSON API end point with Ruby on Rails.
I followed the instruction in the following and was able to create JSON API for my models
http://railscasts.com/episodes/350-rest-api-versioning?view=comments/
I have the following controller:
/api/v1/movies_controller.rb
class MoviesController < ApplicationController
def index
if params[:p].nil?
p = 1
else
p = params[:p].to_i
end
#movies = Movie.order("id DESC").page(p)
end
def show
#movie = Movie.find(params[:id])
end
end
I need to join this with the Genre object where Movie has_many :genres, and Genre belongs_to :movie
However, I'm not able to use the following to get the genres joined with the movie object for the JSON output:
#movie = Movie.find(params[:id], :joins => :genres)
I did notice that the following command is able to generate the joined output in ruby console
#movie.to_json(:include=>:genres)
But then adding this in the controller doesn't show the additional genres fields
Can someone help me please?
Thanks!
My advise: Go with active_model_serializers
Add the following line to your Gemfile
gem 'active_model_serializers'
Do a bundle install afterwards.
After that do a
rails g serializer movie
rails g serializer genre
Than customize the following code:
/api/v1/movies_controller.rb
class MoviesController < ApplicationController
respond_to :json
def index
if params[:p].nil?
p = 1
else
p = params[:p].to_i
end
#movies = Movie.order("id DESC").page(p)
respond_with #movies
end
def show
#movie = Movie.find(params[:id])
respond_with #movie
end
end
app/serializers/movie_serializer.rb
class MovieSerializer < ActiveModel::Serializer
embed :ids, :include => true
attributes :id, :name
has_many :genres
end
app/serializers/genre_serializer.rb
class GenreSerializer < ActiveModel::Serializer
embed :ids, :include => true
attributes :id, :name
end
Have a look at the full documentation of active_model_serializers at
https://github.com/rails-api/active_model_serializers