I followed RBate's Railscast on the subject, but I have a caviat.
The view starts with a form to define the table's variables. On clicking submit, the form posts back to the same view and re-renders the partial (which is just the HTML table). It's not AJAX, it's all form params.
RBates uses a single variable and calls .to_csv on it. I have a complex table with many variables defined by the params and so don't know how to call .to_csv on the entire HTML table.
I need to be able to export just the results in the partial.
Thanks in advance for the ideas.
&&&&&&&& AS REQUESTED, SAMPLE CODE: &&&&&&&&
So, the full code is probably more confusing than helpful, but here's a slimmed down version:
stats/reporter.html.erb: (stat_reporter_path matches this URI)
<%= form_tag( :stat_reporter, method: :post ) do %>
form is in here
<%= submit_tag "Get my report" %>
<% end %>
<div>
<%= render 'stat_select' %>
</div>
stats/_stat_select:
<table>
<thead>
<tr>...column heads...</tr>
</thead>
<tbody>
<% #counties.each do |c| %>
<td><%= c.name %></td>
<% c.programs.each do |p| %>
<td><%= p.name %></td>
<% p.events.each do |e| %>
<td><%= e.name %></td>
...and so on...
</table>
Here's a screenshot
Looking back on this post, I would:
Create a link to a new view and pas all the variables to in the URL.
That view would use all the variables to create an HTML output that could be used to create the to_csv method
Once the csv file was created, the controller would render the original view.
Related
I have a controller:
class UsersController < ApplicationController
def departments
#users_departments = current_user.departments
#new_department = current_user.department.new
end
My view looks similar like this:
<%= form_for #new_department, :url => {:action => "departments"} do |f| %>
.
<% end %>
<% #users_departments.each do |dept| %>
<td><%= dept.name %></td>
<td><%= dept.employees %></td>
<% end %>
#users_departments.each... shows me an empty department. Why? And how to solve that?
First of all - try to use REST
form_for doc
something like that:
<%= form_for #post do |f| %>
will generate link to create action in your UserController
And about #users_departments.each - maybe in your DB current_user.departments.count - return 0
I mean maybe there is no such record in your database.
Ok I found out that the magic thing is called lazy and eager loading.
What I made was changing this:
#users_departments = current_user.departments
to
#users_departments = current_user.departments.find(:all)
Rails seems to be loading the results in the view if it was called. With "find" in place the db get hit and #users_departments fetches "really" the entries. Not in view, like before.
i am getting stuck with using the gem ransack. I have placed ransack in my gemfile and then run bundle install ( though i used just bundle, does that make a difference? i didnt think it did?)
Next i have placed this in my Recipe controller
def all_recipes
#q = Recipe.search(params[:q])
#searchresults = #q.result(:distinct => true)
end
Within my view (all_recipes)i have the search form and block to display my results
<%= search_form_for #q do |f| %>
<%= f.label :dish_name_cont %>
<%= f.text_field :dish_name_cont %>
<%= f.submit %>
<% end %>
---------------------
<% #searchresults.each do |r| %>
<tr>
<td><%= r.dish_name %></td>
</tr>
<% end %>
Ive got two problems, without even conducting a search i get this in my view where the block is
fish and chips my first recipe lasagne Lasagne
and then if i search say las it redirects me to my index page after the get request but as i have no block to display the results i get an undefined error, which is expected.
After this i placed my controller code within the index action and the form and block within the index view and now it all works? Why cant i use the all_recipes action and why does it redirect?
In depth demo, may be helpful - http://railscasts.com/episodes/370-ransack?view=asciicast
Basically I have a table in the index view where if a pictures name = army.unit_name, then it renders that picture. If not, it displays in text that the image is missing. I'm still new at Rails, but there must be a way to put this conditional check somewhere else other than the view. Could someone please enlighten me? Do I do it in the model?
<% #armies.each do |army| %>
<tr>
<% if File.exists?("/users/<name>/Ruby Projects/thrones/app/assets/images/#{army.unit_name}.png") %>
<td><span class="picture-hover"><%= image_tag("#{army.unit_name}.png" %></span></td>
<% else %>
<td>Unit Card art missing</td>
<% end %>
<td><%= link_to army.unit_name, army_path(army) %></td>
</tr>
<% end %>
You can try this
...
<% if Rails.application.assets.find_asset "#{army.unit_name}.png" %>
...
My view:
<h1><%= #territory.name %></h1>
<%= link_to 'List of Territories', territories_path %>
<%= render 'shared/address_form' %>
<table>
<tr>
<td><strong>Name</strong></td>
<td><strong>Street</strong></td>
<td><strong>District</strong></td>
<td><strong>Note</strong></td>
<tr>
<%= #addresses.each do |address| %>
<tr>
<td><%= address.name %></td>
<td><%= address.street %></td>
<td><%= address.district %></td>
<td><%= address.note %></td>
</tr>
<% end %>
</table>
The form I render here is:
<%= form_for [#territory, #new_address] do |f| %>
<div>
<p>
<%= f.label :address %><br />
<%= f.text_area :address %>
</p>
</div>
<div class='file-wrapper'>
<%= f.submit "Submit" %>
</div>
<% end %>
Here is the territories controller, where the instance variable addresses is defined:
class TerritoriesController < ApplicationController
def index
#territories = Territory.all
end
def show
#territory = Territory.find(params[:id])
#new_address = #territory.addresses.build
#addresses = #territory.addresses
end
.
.
.
Why is Rails displaying
#<Address:0x7e088224>#<Address:0x7e0881d4>#<Address:0x7e088134>#<Address:0x7e088094># <Address:0x7e087ff4>#<Address:0x7e087f54>#<Address:0x7e087eb4>#<Address:0x7e087e14>#<Address:0x7e087d74>#<Address:0x7e0bce48>
after the form and before the table?
Thanks
Thomas
Check your layouts (app/views/layouts/*). Most likely you have included some ERB code in the one that is being rendered with this page that displays these addresses. Is that the full code of your view?
Edit: I found your solution. Right now, you have <%= #addresses.each ... %>. The each method runs the block on all elements, and then returns the list of elements. You do not want this code to be displayed. Remove the = so that <%= is just <%
You have some view code somewhere (in a layout or a view helper) that is implicitly calling the to_s method of your Address model instances. Look for something like <%= #address %>.
As you have seen, the non-overridden behaviour of the to_s method is to output the memory address of the object instance.
Those are not memory addresses. Those are instances of your Address class. If you'd override the to_s method in that class, you'd see that output there instead. And the reason you see those object printed out is your use of <%=. Changing this line
<%= #addresses.each do |address| %>
to this
<% #addresses.each do |address| %>
should fix it.
First: I can see no form in your view.
Second: Your view looks ok.
Have a look at your layout files.
I'm trying to build two forms, nested. But all the resources I've found so far deal with how to save the main object, maybe add or remove nested objects, but not saving the entire list elsewhere with the values of the form. Is there a way to do this?
Here're the model I'm working with. I'm trying to create a pc configurator which will allow you to choose different components and quantities, and then you would add to the basket.
So I'm working with three models. Configuration, Configoption, Item.
-- Configuration model
has_many :configoptions
-- Configoption model
belongs_to :configuration
has_many :items
def range
a = []
b = self.quantity_rng.scan(/\w/)
b.each do |p|
a << p.to_i
end
return a
end
-- Item model
belongs_to :configoption
scope :sorted, order('items.position ASC')
The idea is that every configuration has a set of options, say 5. For each of these 5 options there could be a number of available items. For example option 1 is the processor, 2 could be RAM and so on.
-- Configuration controller
def list
#configurations = Configuration.find(:all)
end
def show
#configuration = Configuration.find(params[:id])
#options = #configuration.configoptions
end
-- configuration/show view
<table>
<tr>
<th>Elements</th>
<th>Quantity</th>
</tr>
<%= form_for(:configuration, :remote => true) do |p| %>
<% #options.each do |option| %>
<tr>
<%= form_for(:option, :remote => true) do |f| %>
<% if option.items.count > 1 %>
<th id="<%= option.name %>"> <%= f.select option.name, options_from_collection_for_select(option.items.sorted, 'id', 'name')%></th>
<% else%>
<th id="<%= option.name %>"> <%= f.label(option.items[0].name) %></th>
<% end %>
<% if option.quantity_rng == nil %>
<th id="<%= option.name + "_qty" %>"> <%= f.label(option.quantity) %></th>
<% else%>
<th id="<%= option.name %>"> <%= f.select option.name, option.range, :selected => option.quantity%></th>
<% end %>
<% end %>
<% end %>
</tr>
<% end %>
</table>
So far things are actually good, I can give different items to the options and the .range method let's me say quantity_rng in an option "1,2,3" and will make it into the array [1,2,3] passed for a drop-down if needed.
But now comes the crucial part, actually adding what I selected to the basket. How do I capture what the user has manipulated in the drop downs and store it (not as changes to the configoptions themselves, but as a new object elsewhere?)
BTW I'm using remote => true, because I intend to put some validation rules from jQuery later on, but one step at a time ;)
Thanks a lot!
May be i dint understand well your idea but i thing you need to use p.fields_for as nested options. Look at http://apidock.com/rails/v3.0.0/ActionView/Helpers/FormHelper/fields_for and dot forget to define
def address_attributes=(attributes)
# Process the attributes hash
end
in your model Configuration