Creating Table Filters - ruby-on-rails

I have a simple table with 3 columns like so
table
thead
th Element
th Owner
th Progress
tbody
== render :partial => "element_row" :collection => #elements :as => table_element
Each element is unique, and one owner may have several elements. There are a few different types of "progress" e.g. "started", "not started", and "completed".
I want to create a few links that filter the table. For example, I want to create an started link where when the user clicks on the link, the table is filtered down to only show rows where "started" is displayed. Another example of a filter is by owner.
Does anyone have any suggestions for how to do this?

If you're looking for a gem to help you, Ransack is a great, popular, and active project for searching (and by extension, filtering) ActiveRecord data.
If you check out Ernie's demo site you can see how the search parameters modify the URL through GET queries. You could easily create links like your desired started link to mock these GET form requests.

If you want to do this on the server side, add a filter method to the controller that uses link parameters to filter the #elements.
If you selecting #elements from the database using ActiveRecord, you could do:
#elements = Element.where(progress: params[:progress])
If you just want to filter the #elements in memory, you could do:
#elements = #elements.select{ |element| element.progress == params[:progress] }

Related

How can I populate a form with results from one table which can be edited and saved to another table

The answers to date have not worked so I have re-written my request for help. I hope it is more clear what I am struggling with
I want to move fields from an array (Array1) returned from a table(Table1) into another array (Array2), allow edit and write each record to Table2.
Desired methodology in /new_multiple in the controller:
1. #tasks = Task.find(params[:task_ids]) # returns multiple records
#:task_ids are checkbox tags
#returned from previous form
Note: This works.
2. Move #tasks each into #event and send to existing new.html.erb form for edit and/or confirmation before creation as follows(??):
#tasks.each do |task|
#event = Event.new
#event.location = task.task_location
#event.description = task.task_description
event.start_date = start_date + task.days_from_from_start_task
..... more calculated fields
***send to form for edit, show, create and return for next record (QUESTION 1 below)
end
Note: a redirect and return in *** goes to the form, but the data does not show in the form. I haven't determined if it actually returns.
Questions:
1. Is there a way call a form from the middle of an iteration in the controller and then return to the loop for other records?
2. If not, how do I (can I?)
a)move the multiple #tasks records into an #events array as above (for display in a table in a form for edit)
b)tell the system that each individual row of the array is a new record to be written on submit
Background:
I am creating an application which allows the scheduling of sets of future events. Related tasks (sets) are saved in one table and specify a sequence and a number of days from the first task in the group for that task to occur.
The user starts the process by setting the criteria - task group and the start date from which the events will begin.
The task records are then displayed with the calculated dates/time in a table on a form using a form_tag. At this point, they look like the events that are going to be created. Each line has a check-box tag for selection of tasks in the group. After the user has "ticked" their selection of events (or all), the application returns to the controller to a method called new_multiple_events
Up to this point everything works fine and I can see the selected records that have been chosen (ticked) within the events controller using debugger.
I now want to display each record individually and allow the user to edit the calculated date and time that the event will occur plus a few other fields such as the location and notes etc. and then submit the record for creation in the events table. But this is where I am just NOT getting it.
Models:
Tasks table model:
task.task_description
task.task_location
task.task_notes
task.days_from_start_task
task.task_group_name
Event table model:
event.title = task.task_group_name
event.location = task.task_location
event.description = task.task_notes
event.start_date = start_date + task.days_from_from_start_task
etc...
I have a form which works fine for entry of individual events into the calendar and I would like to move the data from the returned tasks array (plus calculated fields) into the events array as default values for this form which will then allow the user to save the data.
Thanking you in advance for any help you can give.
I don't know how you are prepopulating the event you are editing / creating in the form, but your code states you are doing that in a model. You should however create that logic in the controller before rendering the form, so do something like this:
events_controller.rb
def new
task = Task.find(params[:task_id])
#event = Event.new
#event.title = task.task_group_name
#event.location = task.task_location
#event.description = task.task_notes
#event.start_date = start_date + task.days_from_from_start_task
end
Then create your form like you normally do with the form declaration you already found yourself: form_for #event do |f|
Please consider that I used params[:task_id], suggesting you set up your routes for events nested under tasks so that your url structure looks like (for instance): /tasks/13/events/new
Goog luck
I am closing this issue because I didn't receive a relevant answer. I wanted to allow editing of selected data from one table prior to writing the data, with additional information, to another table. To get around the issue I have instead saved the selected data to the other table and then immediately read the data for edit/update. To the user it looks the same.

Ordering with awesome_nested_set

As I have find out awesome_nested_set is the most popular Rails gem for making categories tree. Unfortunately, it hasn't categories ordering function or it isn't docummented.
Maybe anyone knows how to change these categories order?
Menu
- about
- first page
- second page
- contacts
I don't know how to to add some new categories in the middle of the tree.
Say that the node called first page is an instance of the model Page and has the ID 3. You can do the following:
first_page = Page.find(3)
new_page = Page.create(:name => 'new page')
new_page.move_to first_page, :right
This will create a new page called new page and put it between first page and second page.
EDIT: after looking at the code, it appears that there is now also a method move_to_right_of, which might be more convenient.

Extra, unwanted field from haml block rails partial

I'm outputting a collection in haml
#- if #fields.count>0
.sfields
#= render :partial=>"sfields/field", :collection=>#fields, :as=>:field
= render #fields
When there are zero fields, there is always one phantom field rendered. When I add 'if #fields.count>0' then when there is zero there is no output, but as soon as I add one field I get two rendered, the one I added and a phantom field.
This is the first I've run into this and I'm not sure what I did that is outputting a phantom field. I remember seeing something similar, but can't remember where I saw it, and my search turned up nothing relevant atm.
EDIT 1:
Contents of partial
.sfield
= field.name
.fielditems
#- fields.items each do |i|
#= render :partial=>"items/item", :locals=>{:i => i}
= render field.items
So, there is always an extra sfield hanging around.
EDIT 2
Abstractly, I have this:
Show action -> partial for fields -> partial for field items -> partial for field item choices, 4 different places pulled into one page.
So fields is a collection of items and an item is a collection of choices. Even after going through and making the renders more rails default (e.g. render #fields, render field.items, etc.) I still have that phantom field. I don't want to hide it with js or something (ack awful), so I need to figure some solution which entails more trial and error and reading.
It works, but is ugly with the phantom field hanging on.
EDIT 3
I've taken several steps back combined everything into one template, sans partials. Still there. Something basic I'm doing wrong or missing is adding this phantom field, so annoying. It isn't necessarily the partials then.
EDIT 4: SOLVED
refined the #fields select in the controller to select only fields attached to the item I'm showing
e.g.
#fields = #showing.fields
to
#fields = #showing.fields(:showing_id=>#showing.id)
I'd still like to know why it was doing that grr...
Your #fields wouldn't be a list of hashes would it?
NOTE: Due to backwards compatibility concerns, the collection can’t be one of hashes. Normally you’d also just keep domain objects, like Active Records, in there.
-- http://api.rubyonrails.org/classes/ActionView/Partials.html
Note EDIT 4: SOLVED
refined the #fields select in the controller to select only fields attached to the item I'm showing
e.g.
#fields = #showing.fields
to
#fields = #showing.fields(:showing_id=>#showing.id)

break down a complex search query in Rails 3

I have a controller which has a lot of options being sent to it via a form and I'm wondering how best to separate them out as they are not all being used simultaneously. Ie sometimes no, tags, sometimes no price specified. For prices I have a default price set so I can work around with it always being there, but the tags either need to be there, or not. etc.
#locations = Location.find(params[:id])
#location = #locations.places.active.where("cache_price BETWEEN ? AND ?",price_low,price_high).tagged_with([params[:tags]).order(params[:sort]).paginate :page => params[:page]
I haven't seen any good examples of this, but I'm sure it must happen often... any suggestions? Also, even will_paginate which gets tacked on last should be optional as the results either go to a list or to a google map, and the map needs no pagination.
the first thing to do when refactoring a complex search action is to use an anonymous scope.
Ie :
fruits = Fruit.scoped
fruits = fruits.where(:colour => 'red') if options[:red_only]
fruits = fruits.where(:size => 'big') if options[:big_only]
fruits = fruits.limit(10) if options[:only_first]
...
If the action controller still remains too big, you may use a class to handle the search. Moreover, by using a class with Rails 3 and ActiveModel you'll also be able to use validations if you want...
Take a look at one of my plugins : http://github.com/novagile/basic_active_model that allows you to easily create classes that may be used in forms.
Also take a look at http://github.com/novagile/scoped-search another plugin more specialized in creating search objects by using the scopes of a model.

Collecting additional parameter Ruby on Rails

I am building a project management app and need some help with how to pass a parameter (I think that is how you say it). Here is what I have going on.
I have a table called "proposals" and "proposals" allow you to create multiple concepts per proposal. I have a table called "concepts" and on each "concept" the user can "comment". The way that I have set this up is to generate a table called concept_comments.
Currently the comments are only associated with the concepts but I would like to display all the comment, across all the concepts, for that particular proposal. I am guessing that his has to do with two things:
including another line to collect proposal_id when creating a comment.
Assigning a has_many :concept_comments to the model/proposal.rb file.
Adding map.resources :proposals, :has_many => :concept_comments.
Not sure if that is correct but that is in my head. Only thing I have done so far is to create a column in my concept_comments table called proposal_id. Here is my concept_comments_controller.rb code for 'create':
def create
#concept = Concept.find(params[:concept_id])
#concept_comment = #concept.concept_comments.create!(params[:concept_comment])
respond_to do |format|
format.html { redirect_to #concept }
format.js
end
end
Not quite sure how to tell it to also collect the proposal_id. Somehow I need to tell it to look at the concept_id that has been passed in, then pull the proposal_id number from the concept table, and pass that to the proposal_id in the concept_comments table.
My thinking is that I can then call on the concept_comments table for all entries that have the proposal_id.
I am not even sure if that makes any sense.
well - you could pass in the proposal id, but, if you already have a concept_comment id, you don't need a proposal id
#proposal_comments = ConceptComment.all(:joins => :concept,
:conditions => ["concepts.proposal_id = ?",
#concept_comment.concept.proposal_id])
Where #concept_comment is on a member action of the comments controller - for collection actions, you will need to pass in a proposal id and substitute that in for #concept_comment.concept.proposal_id
Couldn't you just iterate over all of the given proposal's concepts and gather up their comments into one big array, or is this something that's going to be happening millions of times a second?

Resources