rails 4 custom path Sort table - ruby-on-rails

I followed http://railscasts.com/episodes/228-sortable-table-columns to make a sortable table on my records index.erb
So everything works good for that, but now I've gone back to my homepage and put this code in the index.erb for my home object:
<%= link_to "Records Index", records_path %>
And I get a sql error:
So anyway, I went back to records page that was working and saw that my application_helper.rb was doing this to the URL
http://localhost:3000/records?direction=asc&sort=firstname
So now a simple records_path call doesn't work. What would work instead? I tried
records_path & "?direction=asc&sort=firstname"
but that didn't help either. can you help me? thanks!

I thought perhaps I should fix the Def for index in the records controller so I was trying stuff like this
class RecordsController < ApplicationController
...
def index
if sort_column.blank? #sort_direction.nil? || sort_column.nil?
#records = Record.all
else
#records = Record.order(sort_column + " " + sort_direction)
end
end
but that didn't work. so I tried this on the home page:
<%= link_to "Records Index", '\records?direction=asc&sort=firstname' %>
I'm certain there's a much better way to do this using the routes or correcting something in application helper or records controller but this'll work for me.

Related

ApplicationHelper not loaded in Rails 4 engine

Long time reader of SO here. I'm working on a Rails Engine. The big picture problem is that I get a NoMethodError on a helper method living in my Engine's ApplicationHelper. This is for work so I'm going to call the engine Blorge.
I have my helper method that is causing issues anywhere it is called. The Helper method is returning a NoMethodError. I thought maybe I needed to manually add helper Blorge::ApplicationHelper to Blorge::ApplicationController but the issue is still happening.
Am I missing something fundamental about Engines here?
Here is some actual code to give you a better idea of what I'm looking at.
index_header partial
app/views/blorge/shared/_index_header.html.erb
# require_locals is the helper method in question here
<% require_locals ['title'], local_assigns %>
<% title = title.pluralize %>
<section class="main_content-header">
<div class="main_content-header-wrapper">
<%= content_tag :h1, title %>
<div class="main_content-header-save">
<%= link_to "New #{title.singularize}", #new_path, class: "add-button" %>
</div>
</div>
</section>
Pages#home view
app/views/blorge/pages/home.html.erb
<%= render 'blorge/shared/index_header', title: "Welcome, #{current_user.full_name}" %>
...
Engine Application Helper
app/helpers/blorge/application_helper.rb
module Blorge
module ApplicationHelper
def require_locals(local_array, local_assigns)
local_array.each do |loc|
raise "#{loc} is a required local, please define it when you render this partial" unless local_assigns[loc.to_sym].present?
end
end
end
end
Engine Pages Controller
app/controller/blorge/pages_controller.rb
module Blorge
class PagesController < ApplicationController
def home
end
end
end
Engine Application Controller
app/controllers/blorge/application_controller.rb
class Blorge::ApplicationController < ActionController::Base
helper Blorge::ApplicationHelper
...
end
If I restart the server and reload the page, it will usually work just fine, and once it works, the issue doesn't come back for a couple days. After reading Helpers in Rails engine and Rails Engines: Helpers only are reloaded when restarting the server it sounds like I need to include the helper in my application controller with the to_prepare method in my engine.rb file. I am going to try this next but I most want to know if I'm missing something very basic here, If i do just have to add it to engine.rb, can someone explain why?
This might have been too much information, but I'd rather give more than not enough. Thanks in advance.
Edit
the fix seems to have been adding the helpers to application controller within engine.rb. I suspected this would be the fix, but I still have no clue why this is. Does anyone know why I should have to do this?
The Solution
config.to_prepare do
ApplicationController.helper(MyEngineHelper)
end

Rails 3 increment the value of my counter with link_to

Good morning,
In my Ruby On Rails application I am trying to build a stat counter for wins and for losses.
These stats are displayed in the sidebar of my page, which is always visible. For these values i use a model named Stats. The stats should be available global, since I want to display them on every side so they were put into application_helper.rb. I also have two actions, that should be called if you click on the add win / or add loss link, which is only displayed for admins. After clicking the link you get redirected to the main page. At the moment, both counters increase each time someone enters the site or refreshes it. Can you please help me, I am looking to solve this problem now for several hours and i still don't get it.
My application_helper
module ApplicationHelper
def stats
#stats = Stats.find(1)
end
def addwin
#stats = Stats.find(1)
#stats.update_attribute(:wins, #stats.wins+1)
end
def addloss
#stats = Stats.find(1)
#stats.update_attribute(:loss, #stats.loss+1)
end
end
An extract of my application.html.erb file, where the sidebar is located:
<tr><td>Dotards StatsTracker</td></tr>
<tr><td>Wins: </td><td style="color:green"><%= stats.wins%></td></tr>
<tr><td>Losses: </td><td style="color:red"><%= stats.loss%></td></tr>
<hr>
</table >
<%if user_signed_in? && current_user.admin? %>
<small><%= link_to "Add Win", news_index_path(addwin) %>|<%= link_to "Add Loss", news_index_path(addloss)%></small>
<% end %>
Would be awesome if someone could help me, because I don't know what else i can do.
Thank you very much in advance.
news_index_path(addwin)
calls the add win method directly on generation of the page, that's why the counter is increased.
move the two methods to an appropriate controller (maybe news_controller?) and create routes in config/routes.rb like this:
match '/addwin', to: 'news#addwin'
then you get path helpers which you can use like this:
link_to "Add Win" addwin_path
run rake routes to see the helper names generated.
addition: I would also consider your Singleton Stat into a model, and define methods there which are just used by the controller.

Rails file structure: 2 index lists in one view

I'm just helping a friend to create a little project. There are 2 models he likes to put in one view (kind of a summary for both of them, see code below)
class UnnamedController < ApplicationController
def index
#models1 = Model1.all
#models2 = Model2.all
end
end
Then in the view
<% #models1.each do |book| %>
...
<% #models2.each do |book| %>
...
Is that the right way to do it?
How do I name the controller and the view (Rails convention)?
Hope my English is not to bad and Thanks for any help!
Classes in Ruby are conventionally named using CamelCase, so "UnnamedController" is the proper name for your controller, just like "ApplicationController" also is.
The views are named after the action that calls them, so if your action is called "index", then your view filename should be "index.html.erb".
So you're doing it the right way.

Template path in Rails 3

Let's say, I connected the route / to WelcomeController's index action.
Inside of the index.html.erb-Template I want to display the path of the template from Rails.root upwards, ie.
<h1> We are rendering: <%= how_do_i_do_this? %></h1>
to render to
<h1> We are rendering: app/views/presentation/index.html.erb</h1>
In Rails 2 I could access template.path, but this doesn't work anymore
Any ideas?
Because of how template rendering works in Rails, you will now be able to use __FILE__ for this instead. This works for me:
<%= __FILE__.gsub(Rails.root.to_s, "") %>
There may be a better way to do this however, but I couldn't find it when I went looking.
Ryan's answer works. If you also want to put your method in a helper, use Kernel#caller. Here is a method I'm using to do something similar:
def has_page_comment? code = nil
if code.nil?
# grab caller file, sanitize
code = caller.first.split(':').first.gsub(Rails.root.to_s,'').gsub('.html.erb','')
end
...
end

creating dynamic helper methods in rails

I am trying to create a bunch of dynamic helper methods like these:
show_admin_sidebar
show_posts_sidebar
show_users_sidebar
So far I have this in my helper.rb file:
#spits out a partial
def show_sidebar(name, show_sidebar = true)
#content_for_sidebar = render :partial => "partials/#{name}"
#show_sidebar = show_sidebar
end
def show_sidebar?
#show_sidebar
end
In my application layout file I have this: (NB - I'm using HAML):
- if show_sidebar?
= yield(:sidebar)
This allows me to say the following in my views:
- show_sidebar(:foo)
- show_sidebar(:bar)
And this renders the desired partial.
The problem with this is that I can only add one sidebar per page. So, I figure I need to have dynamic methods like: show_admin_sidebar, show_foo_sidebar.
So I have tried to do this:
def show_#{name}_sidebar(show_sidebar = true)
#name = name
#content_for_#{#name}_sidebar = render :partial => "partials/#{#name}"
#show_sidebar = show_sidebar
end
and then in my layout:
- if show_sidebar?
= yield("{#name}_sidebar")
But rails does not like this at all.
I have tried almost everything I can think of in my helper file and nothing works.
The reason I am using helper methods for this is because I want my content div to be 100% page width unless there is a sidebar present in which case the main content goes into a smaller div and the sidebar content goes into it's own..
If I can't get this working, then I can easily fix the problem by just adding the partials manually but I'd like to get my head round this....
Anyone got any experience with this kind of thing?
The entire approach to this was bizarrely overcomplicated, didn't follow Rails conventions at all, nor make the slightest bit of sense, and shame on prior respondents for enabling this approach instead of helping him to simplify. My apologies for being 13 months late with the answer.
Your controller should be deciding if a sidebar is to be shown or not, and setting an instance variable #side_bar_name to either nil or a sidebar name string. Then somewhere in shared view code, probably views/layouts/application.html.erb, you would have something as simple as this:
<% if #side_bar_name %>
<%= render :partial => "partials/#{#side_bar_name}" %>
<% end %>
Or better yet:
<%= render(:partial => "partials/#{#side_bar_name}") if #side_bar_name %>
If you want to use a helper (which is not a bad idea for keeping your code DRY and readable) it would basically be the same code, just moved into the helper.
<%= side_bar_helper %>
def side_bar_helper
render(:partial => "partials/#{#side_bar_name}") if #side_bar_name
end
What the controller does is up to you. It would probably do something like this:
if session[:show_side_bar]
# maybe use cookies instead of session, or store user preference in a database
#side_bar_name = session[:side_bar_name]
end
Here is a solution for you, however I wouldn't suggest too much metaprogramming:
#Add the following snippet to the proper helper module:
['admin','user','whatever'].each do |name|
class_eval{
"def show_#{name}_sidebar(show_sidebar = true)
#name = #{name}
#content_for_#{#name}_sidebar = render :partial => 'partials/#{#name}'
#show_sidebar = show_sidebar
end"
}
end
def show_#{name}_sidebar(show_sidebar = true)
That doesn't look like valid Ruby to me. Are you parsing and evaling this yourself or just throwing that right in the file and expecting it to work?

Resources