How to show search results on rails event_calendar? - ruby-on-rails

I'm new to Rails and I am using rails event_calendar plug-in on my project. I implement it basic CRUD (Create, Read, Update, Delete ) operations on events. But now I need to show my search results on event_calendar. So please can some one give me an idea to implement this on event_calendar ??

From the event_calendar README:
The EventCalendar.new method accepts a hash or block of options, for example:
#event_calendar = EventCalendar.new(2009, 10, :id => 'calendar', :events => Event.all)
#event_calendar = EventCalendar.new(2009, 10) do |c|
c.id = 'calendar'
c.events = Event.all
end
So, instead of Event.all, just use whatever code you're using to get your filtered results.

Related

Is it best practice to use update_attribute action in Rails CRUD Show

I can use it but I am sure if it is a good practice to use update_attribute action in Show action in Rails. If its a bad practice please suggest for the best alternatives since I need to update a column of row on every show action.
My code
def show
#package = Package.friendly.find(params[:id])
#pack = Package.where(:category_id => #package.category_id).sample(4)
#setting = Setting.find(1)
counter = #package.counter
count = counter+1
#package.update_attributes(:counter => count)
end
In Rails CRUD convention "show" should route from an HTTP GET. In general, it's best to avoid modifying any state of the database from a GET action. So, to answer your question, no, it's not a best practice to use update_attribute in a show action.
This is really a odd processing to obtain a count and then increment it by values then update it to table
It's make slower into that
For Best Practices You can implement like this
item = Item.find(1)
item.foo_count # => 0
Item.increment_counter(:foo_count, 1)
item.foo_count # => 0
item.reload
item.foo_count # => 1
item.increment(:foo_count)
item.foo_count # => 2
As per your logic the code will be
Package.increment_counter(:counter, 1)
#package.increment(:counter)

rails mongoid url shortner

I've started creating a model based solution for creating short URLs, but I'm wondering if it wouldn't be better to do it in it's own collection (using mongoid) build an index for the tokens between models then search? Or if there's a gem that exists instead of rolling my own solution.
Right now i'm using Mongoid::Token which generates a unique token (ie cUaIxBu) for the particular collection and then using an additional letter (->(c)UaIxBu) to figure how which controller to route the particular request to.
Any ideas or pointers?
In this example alternatedoma.in/cUaIxBu would point to realdomain.com/cities/1234
routes
get '/:id' => 'home#tiny_url', :constraints => { :domain => 'alternatedoma.in' }
controller
def tiny_url
case params[:id].slice!(0)
when 'f'
#article = Article.find_by_token(params[:id])
redirect_to feature_url(#article)
when 'c'
#city = City.find_by_token(params[:id])
redirect_to city_url(#city)
when 'p'
#place = Place.find_by_token(params[:id])
redirect_to feature_url(#place)
end
end
We're employing an almost identical system in an application that I'm currently working on - and it seems to be working out okay (so far!). The only thing I could think of, is that you could boil down your LoC, as well as easily adding support for other models (if required) in the future:
supported_models = {:a => Article, :c => City, :p => Place}
prefix = params[:id].slice!(0).to_sym
if supported_models.has_key?(prefix)
#obj = supported_models[prefix].find_by_token(params[:id])
redirect_to send(:"#{supported_models[prefix].name.underscore}_url", #obj)
end
Obviously, this would require your routing helpers to follow the the same naming as your models. I.e: Article > article_url, City > city_url, etc.

How can this be re-written as an ActiveRecord query? (Rails)

I have the following method in a controller:
# GET /units/1
def show
#unit = Unit.find(params[:id]
#product_instances = Array.new
current_user.product_instances.each do |product_instance|
if product_instance.product.unit == #unit
#product_instances.push(product_instance)
end
end
... #rest of method
end
As can be seen, I have four tables/models: User, Product, ProductInstance, and Unit. A User has many ProductInstances. Each ProductInstance maps to a Product. A Unit has many Products.
I would like to fetch only the User's ProductInstances that are linked to a Product in the current Unit. The current code does it, but how can I re-write it better? I'd like to get rid of the for-each loop and if statement and replace it with chained ActiveRecord queries, if possible.
I tried something like below but it didn't work:
#product_instances = current_user.product_instances.where(:product.unit => #unit)
Seems you cannot do :product.unit.
I think you can try this
current_user.product_instances.joins(:product).where("products.unit_id = ?",#unit.id)
or with hashes
current_user.product_instances.joins(:product).where(:products => {:unit_id => #unit.id})

Moving of will_paginate to model

On my Question model I have some scopes
scope :recent, order("created_at DESC")
scope :approved, where("status = ?", "approved")
scope :answered, approved.recent.where("answers_count > ?", 0)
On my question controller I'm retrieving questions using the scopes
example 1:
#questions = Question.approved.recent
example 2:
#questions = User.find(session[:user_id]).topics.map { |t| t.questions.approved.recent }.flatten.uniq
I'm trying to put will_paginate on my model to make things easier on the controller but the 2nd example is very tricky as it is using mapping to retrieve questions according to preferences.
I've tried to add this on my model
def self.pagination(page = 1)
self.paginate(:page => page, :per_page => 5)
end
and then on my controller I have
#questions = Question.approved.recent.pagination.(params[:page])
That works fine for the 1st example but I Dont know how to implement that on the 2nd example
Any hints?
This looks like Rails 3. Be sure to use the ~> 3.0.pre2 version of the will_paginate gem.
You can use the paginate method at the end of your chain of scopes. For example, your "example 1" would be:
#questions = Question.approved.recent.paginate(:page => params[:page], :per_page => 20)
I see you created a custom method (pagination) to wrap this pattern, but it's best that you keep this syntax in original form for now, especially since you're dealing with scopes and Relation objects in Rails 3 and will_paginate doesn't have proper support for this yet (but it's coming).
In your "example 2" it seems you only need to fetch the first few recent questions from each topic and that you won't perform a full-blown pagination here (like, going to page 2 and forward). You don't have to use the paginate method here; you can simply use ActiveRecord's limit:
current_user = User.find(session[:user_id])
#questions = current_user.topics.map { |topic|
topic.questions.approved.recent.limit(5).to_a
}.flatten.uniq

Rails doing a FIND with Conditions?

In Rails 3, I created a Search Form that does a FIND with conditions in the Models file.
#projects = find(:all,
:select => 'projects.*',
:conditions => ['name = ?', search_name]
).first
This works great if a name is provided in the searchform (search_name). Problem is if search_name is blank, Rails Errors (can't say I blame it)...
What is the smart way to handle this situation? I'd like, if search_name is blank, to not error but return everything.
Suggestions? Thanks!
You can create a scope to handle this. In your Project model, add something like:
scope :search_by(name), lambda{|name| first.where(:name => name) unless name.blank?}
then in your controller, simply call:
Project.search_by(params[:search])
EDIT:
If you need to serach for multiple fields you can adapt the scope:
scope :search_by(name), lambda{|name| first.includes(:owner).where("projects.name LIKE ? OR owners.name LIKE ?", name, name) unless name.blank?}
if search_name.blank?
#projects = Project.order(:name)
else
#projects = Project.where(:name => search_name)
end
The cleanest way is using lazy loading with the new ActiveRecord functionalities like this:
#projects = Project.order(:name)
#projects = #projects.where(:name => search_name) if search_name
You can add as many conditions as you like this way. They won't be executed until you need the results anyway (with #projects.all or #projects.each, etc...)

Resources