Push name to results unless the name already exists? - ruby-on-rails

I have the following in my tags controller (params[:q] comes from this plugin: http://loopj.com/jquery-tokeninput/). This is basically a slightly modified product of this screencast: http://railscasts.com/episodes/258-token-fields.
tags_controller.rb:
class TagsController < ApplicationController
def index
#tags = Tag.where("name like ?", "%#{params[:q]}%")
results = #tags.map(&:attributes)
results << {:name => "Add: #{params[:q]}", :id => "CREATE_#{params[:q]}_END"}
respond_to do |format|
format.html
format.json { render :json => results }
end
end
I want to only do results << {:name => "Add: #{params[:q]}", :id => "CREATE_#{params[:q]}_END"} only if the name doesn't exist already in #tags. Because right now, it looks like this:
programming #input field
programming #drop-down menu
Add: progamming #drop-down menu
I want it to just display like
programming #input field
Add: progamming #drop-down menu
How to accomplish that?
EDIT:
Here is the model and JavaScript just in case:
application.js
$(function() {
$("#post_tag_tokens").tokenInput("/tags.json", {
crossDomain: false,
prePopulate: $("#post_tag_tokens").data("pre"),
preventDuplicates: true,
theme: "facebook"
});
});
post.rb:
def tag_tokens=(ids)
ids.gsub!(/CREATE_(.+?)_END/) do
Tag.find_or_create_by_name(:name => $1).id
end
self.tag_ids = ids.split(",")
end

You can do this:
#tag = Tag.find_by_name(params[:q])
or
#tag = Tag.name_like(params[:q]) #For this you need to install gem [searchlogic][1]
if #tag.blank?
# Do you things
end

Related

cannot add new tags through jquery.tokeninput

I have watched numerous times both ryan rails-casts, however I'm stuck on this issue couple of days. The main problem is I cannot set new tag records with jquery.tokeninput nor without jquery. I'm pretty sure it has something to do with wrong routes setup... Thank you in advance!
#prepopulating form works fine
_form.html.haml
= f.text_field :tag_list, data: {load: #job.tags.map(&:attributes).to_json }
job.js.coffee
jQuery ->
$('#job_tag_list').tokenInput '/jobs/tags.json',
theme: 'facebook'
prePopulate: $('#job_tag_list').data('load')
job.rb
attr_accessible :tag_list
def self.tokens(query)
tags = ActsAsTaggableOn::Tag.all.where("name LIKE ?", "%#{query}%")
if tags.empty?
[{id: "<<<#{query}>>>", name: "Add new skill: \"#{query}\""}]
else
tags
end
end
def self.tag_list=(arguments)
return if !arguments.is_a?(Hash)
list = arguments[:tag_list]
list.gsub!(/<<<(.+?)>>>/) { ActsAsTaggableOn::Tag.find_or_create_by_name(name: $1).name }
end
jobs_controller.rb
def tags
#tags = ActsAsTaggableOn::Tag.where("tags.name LIKE ?", "%#{params[:q]}%")
respond_to do |format|
format.json {render :json => #tags.tokens(params[:q])}
end
end
routes.rb
resources :jobs do
member do
post 'reply'
end
end
the workable integration of act_as_taggable_one and jquery.tokeninput is provided below:
Extract files from here:https://github.com/loopj/jquery-tokeninput and put in corresponding folders:
vendor/assets/javascripts
*vendor/assets/stylesheets*
gemfile
gem 'acts-as-taggable-on'
application.css
*= require token-input-facebook
application.js
//= require jquery.tokeninput
application.html.erb
<%= javascript_include_tag :defaults, "jquery.tokeninput" %>
jobs.js.coffee
jQuery ->
$('#job_tag_list').tokenInput '/jobs/tags.json',
theme: 'facebook'
prePopulate: $('#job_tag_list').data('load')
allowCustomEntry: true
_form.html.haml
= f.text_field :tag_list, data: {load: #job.tags.map{|t| {id: t.name, name: t.name}}.to_json}
jobs_controller.rb
def tags
#tags = Job.tokens(params[:q])
respond_to do |format|
format.json {render :json => #tags}
end
end
job.rb
acts_as_taggable
attr_accessible :tag_list
def self.tokens(query)
tags = ActsAsTaggableOn::Tag.where("tags.name LIKE ?", "%#{query}%")
if tags.empty?
[{id: "#{query}", name: "Add new skill: \"#{query}\""}]
else
tags
end
end
routes.rb
resources :jobs do
member do
post 'reply'
end
get 'tags', on: :collection
end
$("#skills").tokenInput("/url",{
theme: "facebook",
onResult: function (results) {
if ( results.length == 0 ){
result = new Object();
result['id'] = $('#token-input-skills').val();
result['name'] = $('#token-input-skills').val();
results.push(result);
}
return results;
}
});
i added a function that populates the array with the user's input text if no results are available

datatables via ajax not accepting nested json as correct data

I am trying to implement a slightly more advanced version of the Railscast covering datatables.
I am able to get the table to work via ajax when the controller is providing the WaresDatatable.new(view_context) response by iteslf which was a win.
However, when I try to expand what I am doing and have the json be nested so that datatables and other functions can use the json response the ajax datatable no longer loads data.
I am relatively new to this and have been banging my head for a while against this seemingly small issue.
Controller:
respond_to do |format|
format.html # show.html.erb
#format.json { render :json => #contributor }
format.json {
render :json => {
:warestable => WaresDatatable.new(view_context),
:contributor => #contributor
}
}
end
wares_datatable.rb (as per railscasts and works when json is unnested)
class WaresDatatable
delegate :params, :h, :link_to, :admin_signed_in?, :edit_ware_path, :current_user, to: :#view
def initialize(view)
#view = view
end
def as_json(options = {})
{
sEcho: params[:sEcho].to_i,
iTotalRecords: Ware.count,
iTotalDisplayRecords: wares.count,
aaData: data
}
end
private
def data
if admin_signed_in?
wares.map do |product|
[
link_to(product.name, product),
product.origin,
product.chron_range,
product.desc,
link_to("View", product) + " "+link_to("Edit", edit_ware_path(product), :class => 'btn btn-mini') + " " +link_to("Delete", product, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-mini btn-danger')
]
end
else
wares.map do |product|
[
link_to(product.name, product),
product.origin,
product.chron_range,
product.desc,
link_to("View", product)
]
end
end
end
def wares
#wares ||= fetch_wares
end
def page
params[:iDisplayStart].to_i/per_page + 1
end
def per_page
params[:iDisplayLength].to_i > 0 ? params[:iDisplayLength].to_i : 1
end
def fetch_wares
contributor = Contributor.find(params[:id])
wares = contributor.wares.order("#{sort_column} #{sort_direction}")
wares = wares.page(page).per_page(per_page)
#wares = wares.user.contributor
if params[:sSearch].present?
wares = wares.where("name like :search or origin like :search or desc like :search", search: "%#{params[:sSearch]}%")
end
wares
end
def sort_column
columns = %w[name origin chron_range desc action]
columns[params[:iSortCol_0].to_i]
end
def sort_direction
params[:sSortDir_0] == "desc" ? "desc" : "asc"
end
end
JS.Coffee file
jQuery ->
$('#warestable').dataTable
sPaginationType: "full_numbers"
bJQueryUI: true
bProcessing: true
bServerSide: true
sAjaxSource: $('#warestable').data('source')
JSON response
{"warestable":{"sEcho":0,"iTotalRecords":22,"iTotalDisplayRecords":1,"aaData":[["crap",null,"old","really crappy condition","View"]]},"contributor":{"ad_board":true,"avatar_content_type":"image/jpeg","avatar_file_name":"success.jpg","avatar_file_size":90652,"avatar_updated_at":"2013-05-04T01:54:52Z","created_at":"2013-05-01T05:19:51Z","email":"jack#jack.com","first_name":"jack","id":1,"last_name":"frost","name":null,"ptrgrph_id":null,"resume_content_type":"image/png","resume_file_name":"Argentina.png","resume_file_size":42260,"resume_updated_at":"2013-05-04T03:17:50Z","searchable":"jack frost jack#jack.com bu","selfdescription":"<p><span style=\"font-family:comic sans ms,cursive\">This is my new website info</span></p>\r\n\r\n<p> </p>\r\n\r\n<p> </p>\r\n\r\n<p><span style=\"font-family:comic sans ms,cursive\">Hhaahaha</span></p>\r\n","university":"bu","updated_at":"2013-05-08T01:58:58Z","user_id":4,"ware_id":null}}
Datatables is able to process nested resources so I am pretty sure its just me. If anyone can point me in the right direction much appreciated.
I know this is an old question but look in to sAjaxDataProp.
It lets you set a custom property for instead of aaData, but I haven't found a way to tell datatables to look for sEcho et al elsewhere.

How I can dynamically generate url ( for generating xls report )?

Hello!
I have this trouble: I'm searching reports by date and in html view everything is alright, BUT when I'm rendering xls view error appear, because it didn't receive params, so I need to pass them in URL for xls link_to generator.
My controller:
def show
#website = Website.find(params[:id])
if params[:report] && params[:report][:start_date] && params[:report][:end_date]
#search_by_created_at
#performance_reports = #website.performance_reports.where("created_at between ? and ?", params[:report][:start_date].to_date, params[:report][:end_date].to_date)
else
#performance_reports = #website.performance_reports
end
respond_to do |format|
format.html # index.html.erb
format.xls
format.xml { render :xml => #performance_reports }
end
end
and my generated url looks like:
http://127.0.0.1:3000/websites/25/performance_reports/show?utf8=%E2%9C%93&report[end_date]=07%2F09%2F2012&report[start_date]=04%2F09%2F2012&commit=Run+Report
mine xls url is generated like this:
<%= link_to url_for(:format => 'xls') do%>
<%= image_tag("excel.png", :id => "analytics",:size => '21x23')%> <b>Export</b>
<% end %>
result:
http://127.0.0.1:3000/websites/25/performance_reports/show
Any help will be appreciated.
xls in not available by default.
Add this:
gem "spreadsheet"
gem "to_xls", :git => "https://github.com/dblock/to_xls.git", :branch => "to-xls-on-models"
Register the Excel MIME type in config/initializers/mime_types.rb by adding this:
Mime::Type.register "application/vnd.ms-excel", :xls
Add an as_xls method to model that you want to export for the fields you want.
For example for a User model you might have:
def as_xls(options = {})
{
"Id" => id.to_s,
"Name" => name,
"E-Mail" => email,
"Joined" => created_at,
"Last Signed In" => last_sign_in_at,
"Sign In Count" => sign_in_count
}
end
Add code to the controller:
def index
#users = User.all
respond_to do |format|
format.html
format.xls { send_data #users.to_xls, content_type: 'application/vnd.ms-excel', filename: 'users.xls' }
end
end
Provide a link:
= link_to 'Export', users_path(request.parameters.merge({:format => :xls}))
All code should have a test. You could do something like this:
describe "GET index.xls" do
it "creates an Excel spreadsheet with all users" do
user = Fabricate :user
get :index, :format => :xls
response.headers['Content-Type'].should == "application/vnd.ms-excel"
s = Spreadsheet.open(StringIO.new(response.body))
s.worksheets.count.should == 1
w = s.worksheet(0)
w.should_not be_nil
w.row(0)[0].should == "Id"
w.row(1)[0].should == user.id.to_s
w.row(0)[1].should == "Name"
w.row(1)[1].should == user.name
end
end

Filtering values of index page on values defined in drop down box.rails 3

I am a newbie with rails and I am trying to fliter my index page on values selected by drop down box on index page
For Eg .In my index page I am having a drop down box showing employee names if user selects a value from drop down list the values of index page should filter with that employee name.
Note- Te Employee name is a cross reference field
My Controller Look like
def index
#complaints = Complaint.paginate(:page => params[:page], :per_page => 10)
respond_to do |format|
format.html # index.html.erb
format.json { render :json => #complaints }
end
end
My Index View Looks like
<%= select("employee", "employee_id", Employee.all.collect {|p| [ p.fullname, p.id ] }, { :include_blank => true }) %>
I have tried to answer with whatever I can understand from your question and
I am asssuming u dont want filtering through an ajax call and your complaint table consists of a column named employee_id.
In your index_view add
<%= form_tag 'controllers_index_path' , :method => "get", :id=> 'filter_employees_form' do %>
<p>
<%= select_tag 'employee_id', options_for_select(Employee.all.collect {|p| [p.fullname, p.id ] }, :selected => params[:employee_id]), :prompt => 'Select', :id => 'filter_employees' %>
</p>
<% end %>
Add the following code in the javascript file or add it at the end of your index page.
$(document).ready(function(){
$('#filter_employees').change(function(){
$('#filter_employees_form').submit();
})
})
In controller.rb
def index
#complaints = Complaint.get_complaints(params).paginate(:page => params[:page], :per_page => 10)
respond_to do |format|
format.html # index.html.erb
format.json { render :json => #complaints }
end
end
In complaint.rb(model)
def self.get_complaints(params)
conditions = ['']
conditions = ['complaints.employee_id = ?', params[:employee_id]] if params[:employee_id]
self.where(conditions)
end
Hope this is what you are looking for.

Getting RAILS to return a dateTime in a specific format?

I have this controller:
class SchedulesController "post", :except => :index
def index
#Schedules.create(:id => -1, :deviceId => "2002", :subject => "Test 2", :scheduleTime => Time.new, :repeatEveryYear => "FALSE")
##schedules = Schedules.all
respond_to do |format|
format.html # list.html.erb
format.json { render :json => #schedules.to_json }
end
end
def create
#schedule = Schedules.new.from_json(params[:schedule])
#schedule.save
render :json => "success"
end
end
The Schedule has a dateTime field, how can I get the controller to return this time formatted as "yyyy-MM-dd HH:mm:zzzz" (zzzz = Specific GMT timezone)?
Thank you
Søren
You can specify the date and time formats in the initializers. For instance, create the file config/initializers/time.rb and put the following code:
Time::DATE_FORMATS[:schedule] = "%Y-%m-%d %H:%M:%z"
Then in your Schedule.rb:
def formatted_schedule_time
scheduleTime.to_s(:schedule)
end
And every time you call the to_json method on a Schedule object, you need to do:
#schedule.to_json(:methods => [:formatted_schedule_time])

Resources