Writing a SQL Server query in a Rails controller - sql

I am trying to execute a raw SQL query in my rails controller. I tested the query a database program and it works.
Here is my controller (sites_controller.rb):
class SitesController < ApplicationController
def index
#sites = SELECT * FROM "AM-Martin".dbo.CpCore_Site WHERE "Number" LIKE 'LA%' OR "Number" LIKE 'LC%'
#hash = Gmaps4rails.build_markers(#sites) do |site, marker|
marker.lat site.latitude
marker.lng site.longitude
end
end
end
I keep getting this long error message that it is not liking the way I wrote it.
Can anyone help guide me please?
UPDATE
My controller has changed to:
class SitesController < ApplicationController
def index
query = "SELECT * FROM dbo.CpCore_Site WHERE 'Number' LIKE 'LA%' OR 'Number' LIKE 'LC%'"
#sites = ActiveRecord::Base.connection.execute(query)
#hash = Gmaps4rails.build_markers(#sites) do |site, marker|
marker.lat site.latitude
marker.lng site.longitude
end
end
end
But now I am getting an error for the site.latitude part which says:
undefined method `latitude' for 0:Fixnum
latitude is one of columns from the database table that I am trying to extract.

In rails you can't fire query like this. you can do like this
query = "SELECT * FROM "AM-Martin".dbo.CpCore_Site WHERE "Number" LIKE 'LA%' OR "Number" LIKE 'LC%"
#sites = ActiveRecord::Base.connection.execute(query)
Or
#sites = Model.where("Number LIKE 'LA%' OR Number LIKE 'LC%'")
Hope this will help you.

Related

undefined method `order' for []:Array

I have the following code where I load the activities for the user based on whether or not they are an admin. Users can only see their own activity feed, whereas admins can see the entire stream. This is a precursor to sharing activity feeds with friends, etc.
def index
if current_user?
#incidents = Incident.find_all_by_user_id(current_user.id).order("created_at desc")
else
#incidents = Incident.all.order("created_at desc")
end
end
I am getting the above referenced error(undefined method "order" for []:Array). It seems to be the .order reference, but I have checked the rails Guides and it seems to be correct syntax.
Any ideas?
Try changing the find_by... to where, so:
def index
if current_user?
#incidents = Incident.where(user_id: current_user.id).order("created_at desc")
else
#incidents = Incident.all.order("created_at desc")
end
end
should work :-)
The #index action method can be simplified and optimized (by replacement find_all_by with where) to:
def index
clause = current_user? && Incident.where(user_id: current_user.id) || Incident
#incidents = clause.order("created_at desc")
end

how can I hide resources?

I want to create a page where it shows the resource created by other users but hide the resources created by current_user. is there a method or certain way in which I can do so?
class ExamplesController < ApplicationController
def index
#examples = Example.all.order("created_at DESC")
#creator_examples = Example.where(creator: current_user).order("created_at DESC") <---hide this!!!
end
You can simply manipulate your where clause into something like this:
def index
#examples = Example.all.order("created_at DESC")
#creator_examples = #examples.where.not(id: current_user.id)
end
This is for rails 4, if you're using rails 3
#creator_examples = Example.where("id != ?", current_user.id)
Note -> Example.all in rails 3 returns an array so you can't chain it with where

How to construct a query without triggering it with activeRecord?

I have this code:
def build_query(options)
query = User
query = query.where('first_condition')
query = query.where('second_condition')
query = query.where('items.category_id = ?', category) if (options[:category])
if options[:location]
query = query.where('users.location = ?', options[:location])
end
query = query.order('users.current_sign_in_at DESC')
query = query.limit(MAX_RESULTS)
return query
end
Unfortunately, a request is trigerred each time I do query = query.where(...)
I could just chain all where clauses (where().where()...), but then how do I keep my ifs ?
Is there a way to tell ActiveRecord not to trigger the query ?
You can collect all conditions in conditions variable:
conditions = {}
conditions.merge('first_condition') if ...
conditions.merge('second_condition') if ...
# snip
User.where(conditions).order('users.current_sign_in_at DESC').limit(MAX_RESULTS)

ActiveRecord - NoMethodError

These AREL queries do not work in Rails 3. Can someone help me decipher this error?
NoMethodError (undefined method `id' for #<ActiveRecord::Relation:0xabf6f44>):
app/controllers/admin_controller.rb:206:in `save_user'
All of these cause the same error as shown above
#existing = Privilege.find(:first, :conditions => "b2b_user_id = #{#user.id} AND vendor_id = #{#vendor_id}")
#existing = Privilege.find_by_sql("SELECT * FROM b2b_privileges WHERE b2b_user_id = ? AND vendor_id = ? LIMIT 1",#user.id,#vendor_id)
#existing = Privilege.where(:b2b_user_id => #user.id, :vendor_id => #vendor_id)
But when I change this:
#user = B2bUser.where("id = ?",params[:id])
To this:
#user = B2bUser.find_by_id(params[:id])
The queries work. Why?
Thanks
What you're getting whn using method "where" is just a relation, think of it like a query that is still not executed, then you have to call a method to retrieve data eg: first, all, last, to_a, etc
#user = B2bUser.where("id = ?",params[:id]) #this is just an active record relation
#user = B2bUser.where("id = ?",params[:id]).first #this is your object
Read a little about relations, they're really interesting
relations

pulling one field of a record into an array in a Rails 3 app

Rails 3 noob here. Currently the code in my controller below is getting the whole record in my database. I am trying to populate the array with one integer, not the whole record. The integer is contained in a table "answers" and the field name is "score". How can i modify this line in my controller to get just the one field?
#questions.each do |s|
#ans[s.position] = Answer.where("question_id = ? AND user_id = ?", s.q_id, current_user.id )
end
UPDATE FOR CLARIFICATION: The :score can be any integer from 0 to 5. I would like to populate #ans[s.position] with the integer.
Thanks.
You're very close
#questions.each do |s|
#ans[s.position] = Answer.where("question_id = ? and user_id = ?",s.q_id,current_user.id).select(:score).first.try(:score)
end
You need to select "score" from Answer, then you need to retrieve it from the object.
Since where could potentially return many Answers, use first to pull off the first Answer, and then score to project out the score field.
answers = Answer.where("question_id = ? AND user_id = ?", s.q_id, current_user.id )
score = answers.first.score
All together it would be:
#questions.each do |s|
#ans[s.position] = Answer.where("question_id = ? AND user_id = ?", s.q_id, current_user.id ).first.score
end
As an optimization to only retrieve score from the database, instead of answers.*, you could use select(:score).
#questions.each do |s|
#ans[s.position] = Answer.where("question_id = ? AND user_id = ?", s.q_id, current_user.id ).select(:score).first.score
end
See Active Record Query Interface for more about using select.
Just include them.
#questions = Question.includes(:answers).select(:position)
Or use this
#questions = Question.select(:position)
#questions.each{ |s| #ans[s.position] = s.answers.where(:user_id => current_user.id) }