In my view I send an ajax request to get the device_ports of a particular device.
Previously I used
def get_device_ports
if params[:id] != ''
#device_ports = Device.find(params[:id]).device_ports.all(:order => 'id ASC')
output = '<option value="">Select Device Port...</option>'
#device_ports.each do |device_port|
output = output + '<option value="' + device_port.id.to_s + '">' + device_port.name + '</option>'
end
render :text => output
else
render :text => '0'
end
end
Which worked one but now having changed my query I get an error undefined method 'name' for [268, "test-1"]:Array with 268 and test-1 being the id and name of the first row of results.
This is my updated code:
def get_device_ports
if params[:id] != '' and params[:device_id] != ''
# #device_ports = Device.find(params[:id]).device_ports.all(:order => 'id ASC')
device_id = params[:device_id]
# Need a list of ports that aren't in use or are multiuse
#device_ports = ActiveRecord::Base.connection.execute('SELECT DISTINCT d.id, d.name FROM device_ports d LEFT OUTER JOIN circuits c ON c.physical_port_id = d.id WHERE (c.physical_port_id IS NULL AND d.device_id = ' + device_id + ') OR (d.multiuse = 1 AND d.device_id = ' + device_id + ') ORDER BY d.id ')
output = '<option value="">Select Device Port...</option>'
#device_ports.each do |device_port|
output = output + '<option value="' + device_port.id.to_s + '">' + device_port.name + '</option>'
end
render :text => output
else
render :text => '0'
end
end
I'm just not sure why I'm getting the error, I imagine it's something trivial but due to the amount of different NoMethodError questions it's hard to find an answer.
You are having this problem because you aren't using ActiveRecord as an ORM to wrap the object, but rather executing a query and working on the resulting series of arrays. I would recommend changing your query like so:
#device_ports = Device.find(device_id).device_ports.includes(:circuits).
where('device_ports.multiuse = 1 OR circuits.id IS NULL').
order('device_ports.id').distinct
If you absolutely want to avoid ActiveRecord, then don't use id and name, but rather treat each record as an array:
output << %Q{<option value="#{device_port.first}">#{device_port.last}</option>}
UPDATE
I just noticed that you're using RoR-2. Although more painful, you can still use an ActiveRecord query like so:
#device_ports = DevicePort.all(
:joins => "LEFT JOIN circuits c ON device_ports.id = c.devic_port_id",
:conditions => ['device_ports.device_id = ? AND (device_ports.multiuse = 1 OR c.id IS NULL)', device_id],
:order => 'device_ports.id',
:select => 'DISTINCT device_ports.id, device_ports.name')
Related
Having issue while passing limit per paje display 50 records.
if params[:limit].present? && params[:offset].present?
offset_value = (params[:offset].to_i - 1) * params[:limit].to_i
limit << " LIMIT #{params[:limit].to_i} OFFSET #{offset_value}"
elsif params[:limit].present?
limit << " LIMIT #{params[:limit].to_i}"
else
if params[:offset].present?
offset_value = (params[:offset].to_i - 1) * 50
limit << " LIMIT 50 OFFSET #{offset_value}"
else
limit << " LIMIT 50"
end
end
query << "
select pp.id,
ud.last_name || ' ' || ud.first_name as full_name,
pp.image_file_name,
pp.gender_type ,
pp.no_of_view_for_last_30_days ,
pp.no_of_likes ,
pp.no_of_comments,
pp.tenpo_name_display,
pp.online_open ,
pp.online_comment from product pp
inner join user_details ud on pp.user_id = ud.user_id
inner join user_labels ul on ul.user_id = ud.user_id
where pp.flag = false and end_dt is null"
#posts = ActiveRecord::Base.connection.execute(query + limit)
having error in view, below line.
<%= will_paginate #posts, :renderer => BootstrapPagination::Rails %>
trying to make pagination, but having error like total_pages after passing objet to view.
It seems like you're trying to use will_paginate gem, aren't you?
If that's the case, you're doing too much in your controller. will_paginate is supposed to do all those calculations (offsets etc.) for you:
#posts = Post.paginate(page: params[:page])
Please note also that https://github.com/bootstrap-ruby/will_paginate-bootstrap (which it seems you're trying to use) is no longer maintained.
I done with this. get total count from query.
query << " select count(*) OVER() AS total_count,
pp.id,
ud.last_name || ' ' || ud.first_name as full_name,
pp.image_file_name,
pp.gender_type ,
pp.no_of_view_for_last_30_days ,
pp.no_of_likes ,
pp.no_of_comments,
pp.tenpo_name_display,
pp.online_open ,
pp.online_comment from product pp
inner join user_details ud on pp.user_id = ud.user_id
inner join user_labels ul on ul.user_id = ud.user_id
where pp.flag = false and end_dt is null"
offset = params[:page].present? ? (params[:page].to_i - 1) * 30 : 0
#posts = ActiveRecord::Base.connection.execute(query + 'limit 30 offset ' + offset.to_s )
posts_count = !#posts.nil? ? #posts.first["total_count"] : 0
#post_count = #posts.to_a.paginate(page: params[:page], per_page: 30, total_entries: posts_count)
passing param as total_entries to pagination. It's work.
I am facing the below error after I removed two fields middle_name, last_name from the Student migration thru another migration. below are the errors.
Searchlogic::NamedScopes::OrConditions::UnknownConditionError in StudentController#advanced_search
The condition 'last_name' is not a valid condition, we could not find any scopes that match this.
RAILS_ROOT: /root/ansipro342
Application Trace | Framework Trace | Full Trace
/root/ansipro342/vendor/plugins/searchlogic/lib/searchlogic/named_scopes/or_conditions.rb:96:in `interpolate_or_conditions'
/root/ansipro342/vendor/plugins/searchlogic/lib/searchlogic/named_scopes/or_conditions.rb:75:in `each'
/root/ansipro342/vendor/plugins/searchlogic/lib/searchlogic/named_scopes/or_conditions.rb:75:in `interpolate_or_conditions'
/root/ansipro342/vendor/plugins/searchlogic/lib/searchlogic/named_scopes/or_conditions.rb:36:in `or_conditions'
/root/ansipro342/vendor/plugins/searchlogic/lib/searchlogic/named_scopes/or_conditions.rb:19:in `or_condition?'
/root/ansipro342/vendor/plugins/searchlogic/lib/searchlogic/named_scopes/or_conditions.rb:10:in `condition?'
/root/ansipro342/vendor/plugins/searchlogic/lib/searchlogic/search/scopes.rb:10:in `scope?'
/root/ansipro342/vendor/plugins/searchlogic/lib/searchlogic/search/method_missing.rb:16:in `method_missing'
/root/ansipro342/vendor/plugins/searchlogic/lib/searchlogic/search/conditions.rb:19:in `send'
/root/ansipro342/vendor/plugins/searchlogic/lib/searchlogic/search/conditions.rb:19:in `conditions='
/root/ansipro342/vendor/plugins/searchlogic/lib/searchlogic/search/conditions.rb:15:in `each'
/root/ansipro342/vendor/plugins/searchlogic/lib/searchlogic/search/conditions.rb:15:in `conditions='
/root/ansipro342/vendor/plugins/searchlogic/lib/searchlogic/search/date_parts.rb:19:in `conditions='
/root/ansipro342/vendor/plugins/searchlogic/lib/searchlogic/search/base.rb:18:in `initialize'
/root/ansipro342/vendor/plugins/searchlogic/lib/searchlogic/search/implementation.rb:10:in `new'
/root/ansipro342/vendor/plugins/searchlogic/lib/searchlogic/search/implementation.rb:10:in `search'
/root/ansipro342/app/controllers/student_controller.rb:816:in `advanced_search'
Request
Parameters:
{"search"=>{"order"=>"",
"first_name_or_middle_name_or_last_name_or_admission_no_like"=>"Imran"},
"commit"=>"Search"}
Following is the code area from Student controller where line 816 exists
def advanced_search
#search = Student.search(params[:search])
unless params[:search].present?
#batches = Batch.all
else
if params[:search].present?
#students = Array.new
if params[:advv_search].present? and params[:advv_search][:course_id].present?
unless params[:search][:batch_id_equals].present?
params[:search][:batch_id_in] = Batch.find_all_by_course_id(params[:advv_search][:course_id]).collect{|b|b.id}
end
end
if params[:search][:is_active_equals]=="true"
#students = Student.ascend_by_first_name.search(params[:search]).paginate(:page => params[:page],:per_page => 30)
elsif params[:search][:is_active_equals]=="false"
#students = ArchivedStudent.ascend_by_first_name.search(params[:search]).paginate(:page => params[:page],:per_page => 30)
else
#students = [{:student => {:search_options => params[:search], :order => :first_name}},{:archived_student => {:search_options => params[:search], :order => :first_name}}].model_paginate(:page => params[:page],:per_page => 30)#.sort!{|m, n| m.first_name.capitalize <=> n.first_name.capitalize}
end
#searched_for = ''
#searched_for += "<span>#{t('name')}/#{t('admission_no')}: " + params[:search][:first_name_or_admission_no_like].to_s + "</span>" if params[:search][:first_name_or_admission_no_like].present?
#searched_for += "<span>#{t('name')}: " + params[:search][:first_name_like].to_s + "</span>" if params[:search][:first_name_like].present?
#searched_for += " <span>#{t('admission_no')}: " + params[:search][:admission_no_equals].to_s + "</span>" if params[:search][:admission_no_equals].present?
if params[:advv_search].present? and params[:advv_search][:course_id].present?
course = Course.find(params[:advv_search][:course_id])
batch = Batch.find(params[:search][:batch_id_equals]) unless (params[:search][:batch_id_equals]).blank?
#searched_for += "<span>#{t('course_text')}: " + course.full_name + "</span>"
#searched_for += "<span>#{t('batch')}: " + batch.full_name + "</span>" if batch.present?
end
Please help I dont know where the last_name exists that its showing in error, I am very new to ruby on rails nd need this importantly.
Thanks in advance.
Thanks for the replies, The problem solved.
The problem was in the index migration, actually I removed the columns from the create migration but it was already there in index migration.
Dude that code is huge and very unlikely that someone will understand it by reading it one time..
Install rubocop or some other lint tool and clean that mess.
How to update field using other fields in a single query ?
sql:
"UPDATE table_name SET field1=fields2 + 1 where id=123"
Tried these things, but didn't work
Model.update(123, :field => "field2 + 1")
Model.update(123, :field => :field2 + 1)
Model.update(123, "field = field2 + 1")
Don't want to do it in 2 query.
Model.update_all("field = field2 + 1", {:id => 123})
The second argument is conditions, on which the update should happen
I have a model that looks like this:
class StopWord < ActiveRecord::Base
UPDATE_KEYWORDS_BATCH_SIZE = 1000
before_save :update_keywords
def update_keywords
offset = 0
max_id = ((max_kw = Keyword.first(:order => 'id DESC')) and max_kw.id) || 0
while offset <= max_id
begin
conditions = ['id >= ? AND id < ? AND language = ? AND keyword RLIKE ?',
offset, offset + UPDATE_KEYWORDS_BATCH_SIZE, language]
# Clear keywords that matched the old stop word
if #changed_attributes and (old_stop_word = #changed_attributes['stop_word']) and not #new_record
Keyword.update_all 'stopword = 0', conditions + [old_stop_word]
end
Keyword.update_all 'stopword = 1', conditions + [stop_word]
rescue Exception => e
logger.error "Skipping batch of #{UPDATE_KEYWORDS_BATCH_SIZE} keywords at offset #{offset}"
logger.error "#{e.message}: #{e.backtrace.join "\n "}"
ensure
offset += UPDATE_KEYWORDS_BATCH_SIZE
end
end
end
end
This works just fine, as the unit tests show:
class KeywordStopWordTest < ActiveSupport::TestCase
def test_stop_word_applied_on_create
kw = Factory.create :keyword, :keyword => 'foo bar baz', :language => 'en'
assert !kw.stopword, 'keyword is not a stop word by default'
sw = Factory.create :stop_word, :stop_word => kw.keyword.split(' ')[1], :language => kw.language
kw.reload
assert kw.stopword, 'keyword is a stop word'
end
def test_stop_word_applied_on_save
kw = Factory.create :keyword, :keyword => 'foo bar baz', :language => 'en', :stopword => true
sw = Factory.create :keyword_stop_word, :stop_word => kw.keyword.split(' ')[1], :language => kw.language
sw.stop_word = 'blah'
sw.save
kw.reload
assert !kw.stopword, 'keyword is not a stop word'
end
end
But mucking with the #changed_attributes instance variable just feels wrong. Is there a standard Rails-y way to get the old value of an attribute that is being modified on a save?
Update: Thanks to Douglas F Shearer and Simone Carletti (who apparently prefers Murphy's to Guinness), I have a cleaner solution:
def update_keywords
offset = 0
max_id = ((max_kw = Keyword.first(:order => 'id DESC')) and max_kw.id) || 0
while offset <= max_id
begin
conditions = ['id >= ? AND id < ? AND language = ? AND keyword RLIKE ?',
offset, offset + UPDATE_KEYWORDS_BATCH_SIZE, language]
# Clear keywords that matched the old stop word
if stop_word_changed? and not #new_record
Keyword.update_all 'stopword = 0', conditions + [stop_word_was]
end
Keyword.update_all 'stopword = 1', conditions + [stop_word]
rescue StandardError => e
logger.error "Skipping batch of #{UPDATE_KEYWORDS_BATCH_SIZE} keywords at offset #{offset}"
logger.error "#{e.message}: #{e.backtrace.join "\n "}"
ensure
offset += UPDATE_KEYWORDS_BATCH_SIZE
end
end
end
Thanks, guys!
You want ActiveModel::Dirty.
Examples:
person = Person.find_by_name('Uncle Bob')
person.changed? # => false
person.name = 'Bob'
person.changed? # => true
person.name_changed? # => true
person.name_was # => 'Uncle Bob'
person.name_change # => ['Uncle Bob', 'Bob']
Full documentation: http://api.rubyonrails.org/classes/ActiveModel/Dirty.html
You're using the right feature but the wrong API.
You should #changes and #changed?.
See this article and the official API.
Two additional notes about your code:
Never rescue Exception directly when you actually want to rescue execution errors. This is Java-style. You should rescue StandardError instead because lower errors are normally compilation error or system error.
You don't need the begin block in this case.
def update_keywords
...
rescue => e
...
ensure
...
end
User table:
name lastname
Bob Presley
Jamie Cox
Lucy Bush
Roman Cox
Find users
q = Query.new("Bob Presley, Cox, Lucy")
q.find_users => {0=>{:name=>"Bob", :lastname=>"Presley"}, 1=>{:lastname=>"Cox"}, 2=>{:name=>"Lucy"}}
Question:
I've got hash with few names and lastnames. I need to build Activerecord query to fetch all users from that hash.
If i have name and lastname I should find user with exactly the same name and lastname.
If I have only lastname or name I should find all users with this name or lastname. So when i search for :lastname => Cox it should return two users [Roman Cox,Jamie Cox]
I can do
object = []
hash = q.find_users
hash.each do |data|
#Pseudocode
# object << User.where(:name => if data[:lastname] exist, :lastname => if data[:name] exist)
end
But I think it is higly inefficient. How should I do this ?
Environment
rails: 3.0.3
ruby: 1.9.2-head
gem: meta_search https://github.com/ernie/meta_search
I'm sure this can be refactored nicely (hint!), but this code below will construct a SQL which can be used in a sub-select.
Code below does not sanitize the input values.
Note that you should sanitize the values in the h hash!
h = {0=>{:name=>"Bob", :lastname=>"Presley"}, 1=>{:lastname=>"Cox"}, 2=>{:name=>"Lucy"}}
conditions = ""
h.each_pair do |k,v|
if not conditions.empty?
conditions += " or "
end
conditions += "("
a_condition = ""
v.each_pair do |a,b|
if not a_condition.empty?
a_condition += " and "
end
a_condition += "#{a.to_s} = '#{b}'"
end
conditions += a_condition
conditions += ")"
end
conditions = "("+conditions+")"
p conditions
# => "((name = 'Bob' and lastname = 'Presley') or (lastname = 'Cox') or (name = 'Lucy'))"
# use the generated SQL conditions to find the users
#users = User.find(:all, :conditions => "(#{conditions})")