Binding Variables in Ruby - mysql

I currently have a table that is listed as follows:
projects = Project.find(:all, :conditions => [conditions + "AND (name LIKE ? OR description LIKE ?)", "%#{params[:query]}%", "%#{params[:query]}%"])
where
conditions = Project.in_used_projects(:alias => "projects")
However I need to include a 3rd variable which is not from the Project table but from a Tags table. The column I need is Tag - > Names. Is there anyway I can bind variables from another table in Ruby? The Project.find(all) automatically passes the SELECT * FROM Project into MYSQL. Someone has suggested using a join function, but I'm not sure how this would work. Any ideas?
EDIT 1
I have tried the suggested answer of using
projects = Project.find(:all, :joins => "tags", :conditions => [conditions + "AND (projects.name LIKE ? OR description LIKE ? OR tags.name LIKE ?", ["%#{params[:query]}%" * 3]].flatten)
but now I am getting another error
Mysql::Error: Unknown table 'projects': SELECTprojects.* FROMprojectstags WHERE ((projects.status = 2)AND (projects.name LIKE '%%' OR projects.description LIKE '%%' OR tags.name LIKE '%%')
Very strange considering the projects table exists. Why isn't Ruby recognizing it now that i've included another table?

Try this out for size:
projects = Project.find(:all, :joins => "tags", :conditions => [conditions + "AND (projects.name LIKE ? OR description LIKE ? OR tags.name LIKE ?", ["%#{params[:query]}%" * 3]].flatten)
The :joins option tells Active Record to perform an SQL join onto the tags table, which will allow you to perform queries on the tags column. Also take note in this example how I've added the projects. prefix to your original name column. This is so your database doesn't get confused what name column you want; the one from the projects or the tags table.

Do you have any relationship between projects and tags? If the reason for your query is that there is, it should be reflected in the model (for ex with a HABTM), which would also enable you to easily filter based on that relationship without the need to have complex SQL queries crafted.

Turns out that it was just a simple syntax error
projects = Project.find(:all, :joins=>:tags, :conditions => [conditions + "AN rojects.name LIKE ? OR projects.description LIKE ? OR tags.name LIKE ?)", "%# ams[:query]}%", "%#{params[:query]}%", "%#{params[:query]}%"])
is the correct syntax. The :joins needs to be followed by :tags, not by "tags"
Thanks again for everyone's help

Related

Query Between Two Tables Using Ruby

My code is this
contact = UserContact.find(:all,:select=>"distinct app_id,number",:conditions=>"number ='1234'")
arr=[]
contact.each do|c|
arr << c.app_id
end
name=User.find(:all,:conditions=>"id in(#{arr.join(',')}")
I takes two much time Can i do this using join
Thanks
You should do smth like this
User.find(:all, :joins => :user_contacts, :conditions => "user_contacts.number = '1234'")
user should have association. In user.rb should be:
has_many :user_contacts, :foreign_key => :app_id
But it is bad style to name column "app_id" it should be "user_id"(convention over configuration). Renamed it. After rename you can remove ", :foreign_key => :app_id"
Unfortunately you can NOT do "includes" and "select" in the same Active record Query. So this will not work...
contacts = UserContact.includes(:users).where("number = ?", '1234').select(:app_id, :number).uniq
BUT.
FIRST: app_id looks like it should be called "user_id"
SECOND: What version of Rails are you using? You might want to use the "pluck" method if you are using rails 3.2. Hence
user_ids = UserContact.where("number = ?", '1234').pluck(:app_id).uniq
users = User.where(:id => user_ids)
THIRD: in ruby instead of doing this:
arr=[]
contact.each do|c|
arr << c.app_id
end
do this:
arr = contact.inject([]) {|arr, c| arr << c.app_id}
FOURTH: As in all my examples your syntax is mostly Rails 2. I assume you are using rails 2? If so you might need to upgrade.
FIFTH: use plural variable names if you return more than one object. Hence
contact = UserContact.....
name=User.....
should be
contacts = UserContact.find.....
users = User.find.....
LAST:
User.joins(:user_contacts).where("user_contacts.number = ?", '1234')
might be good

Codeigniter mysql where not equal to query

Mysql codeigniter query is not working properly.
Suppose if mysql table looks like this:
user_id|user_name
1|john
2|alex
3|sam
Here user_name is unique
The following query should return false if user_name=john and user_id=1 and true if say user_name=john and user_id=2.
$this->db->get_where('user', array('user_name' => $name,'user_id !=' => $userid));
But it returns true in the case user_name=john and user_id=1.
Can anyone suggest me an alternative way of querying not equal to.
print($this->db->last_query()) gives:
SELECT * FROM (user) WHERE user_name = 'john' AND user_id != '1'
Why dont you use simple $this->db->query('your query');
Simply try this, Add the desired condition in the where function.
$this -> db -> where('invitee_phone !=', $user_phone);
You can go follwoing way too. It work for me
$total = 5;
$CI = get_instance();
$CI->load->database();
$CI->db->order_by('id','asc');
$topusers = $CI->db->get_where('users',array('user_type != 1 && `status` =' => 1),$total,0);
echo $CI ->db ->last_query();
die;
and if still not work for you can go with #rohit suggest: $this->db->query('your query');
Type 1:
Using ->where("column_name !=",$columnname) is fine for one column.
But if you want to check multi columns, you have to form an array inside where clause.
Like this
$whereArray = array(
"employee_name" => $name,
"employee_id !=" => $id,
);
$this->db->select('*')->from('employee')->where($whereArray);
Type 2:
We can just write exactly what we want inside where.
Like
$thi->db->where(("employee_id =1 AND employee name != 'Gopi') OR designation_name='leader#gopis clan'");
Type 2 is good for working with combining queries, i mean paranthesis "()"
you can follow this code:
$query = $this->db->select('*')->from('employee')->where('user_name', $name)->where('user_id !=', $userid)->get();
$last_query = $this->db->last_query();
$result = $query->result_array();
if you pass $name = 'john' and $userid = '1' then it return empty array.
The problem with using $this->db->query('your query'); is that it is not portable. One of the most important reasons to embrace the query builder methods is so that no matter what database driver you use, CodeIgniter ensures that the syntax is appropriate.
If a bit of discussion was possible, I'd probably like to hear why you need composite primary identifiers in your table and I'd like to see what your table schema looks like. However, I think the time for discussion has long passed.
Effectively, you want to return a boolean result stating the availability of the combination of the username AND the id -- if one is matched, but not both, then true (available).
To achieve this, you will want to search the table for an exact matching row with both qualifying conditions, count the rows, convert that integer to a boolean, then return the opposite value (the syntax is simpler than the explanation).
Consider this clean, direct, and portable one-liner.
return !$this->db->where(['user_name' => $name,'user_id' => $userid])->count_all_results('user');
this will return false if the count is > 0 and true if the count is 0.

Rails Joins and Like?

I am trying to use joins in rails to retrieve some info base on a search field but I cannot seem to find the good syntax,
I have two table savings and product and saving are saving for a product. What I want is to find a saving based on the name of the product I found that this work :
Saving.all(:joins => :product, :conditions => { :products => { :title => 'Title Name' } })
It retrieve the saving corresponding to the product named Title Name.
Now how can I change that to find the savings where product title contains params[:title] ?
Thanks,
Saving.joins(:product).where('products.title like ?', "%#{params[:title]}%")
Saving.joins{product}.where{(savings.products.title =~ my{"%#{params[:term]}%"} } with squeel

RoR: Condition Always False - Why?

I am working in Rails 2.3.x on a learning management system. Here's my code:
-#users.each do |user|
%tr
%td
=link_to h(user.name), :action => :show_user, :id => user.id
%td="#{h user.grade_level}"
-if QuizResult.find_by_user_id(#user_id).present?
="#{(QuizResult.average('score', :conditions => 'user_id = #{#user.id}') * 100).round}%"
-else
%em No quizzes taken
My quiz_results table has columns for user_id and score, among others. I have a record with a user_id (3907) and result (0.1), and two users I'm looking at with no records in the quiz_results table.
The display says "No quizzes taken" for all three, which leads me to believe that this line is false no matter what:
-if QuizResult.find_by_user_id(#user_id).present?
Any ideas how to fix?
Change #user_id to user.id in the if statement and #user.id to user.id. Also change the single quotations to double quotations or using string interpolation won't work.
I guess you need to change #user.id to user.id.
As the answer to second part of your question, I think you can't have a nested evaluated string (the nested #{}). You need to compute the results first, then evaluate and output it in HAML:
-averge = QuizResult.average('score', :conditions => 'user_id = #{#user.id}') * 100).round
="#{average}%"

CakePHP: finding information in distantly related models

I have a News model, which has a HABTM relationship with an Artists model, and an artist in turn hasMany tourdates.
If I want to find all tourdates related to the current news item, what is an efficient way of phrasing that for CakePHP?
This is what I have so far; I'm wondering if (a) it looks like it should work, and (b) if there's any more concise way of writing it:
$relatedartists = $this->News->ArtistsNews->find('list', array(
'conditions'=>array('ArtistsNews.news_id' => $id),
'fields'=>array('artist_id')
));
$livedates = $this->News->Artists->Tour->find('all', array(
'conditions'=>array('Tour.artist_id'=> $relatedartists,
'date >= ' . time()),
'order'=>'date ASC'
));
What you have is pretty good. I always prefer to use multiple queries rather than use massive joins which create temporary tables. It can reduce performance somewhat.
You might also try something like the below
$opts = array(
'conditions' => array(
'ArtistsNews.news_id' => $id
)
);
$this->News->Artists->recursive = 2;
$this->News->Artists->find('all', $opts);
Something along the likes of this query will also get you what you need (haven't error checked)