undefined local variable or method `browse_path' - ruby-on-rails

I'm getting this error
NameError in Browse#index
undefined local variable or method `browse_path'
Here's the code in view where the error is raised
<li><%= link_to "Browse", browse_path %></li>
Here's the controller
class BrowseController < ApplicationController
def index
#tags = tag.find(:all, :order => 'created_at DESC')
end
end
and finally my routes
get'/browse' => 'browse#index', :as => :index
anyone know what is causing this?

Try :as => :browse for the named route.

Related

Undefined Method 'underscore'

I'm trying my hand at STI using Thibault's tutorial: https://samurails.com/tutorial/single-table-inheritance-with-rails-4-part-3
It's been working fine up till the dynamic paths part where I get 'undefined method `underscore' for nil:NilClass' for this snippet
def format_sti(action, type, post)
action || post ? "#{format_action(action)}#{type.underscore}" : "#{type.underscore.pluralize}"
end
Routes:
resources :blogs, controller: 'posts', type: 'Blog' do
resources :comments, except: [:index, :show]
end
resources :videos, controller: 'posts', type: 'Video'
resources :posts
Post controller:
before_action :set_post, only: [:show, :edit, :update, :destroy]
before_action :set_type
def index
#posts = type_class.all
end
...
private
def set_type
#type = type
end
def type
Post.types.include?(params[:type]) ? params[:type] : "Post"
end
def type_class
type.constantize
end
def set_post
#post = type_class.find(params[:id])
end
Posts Helper:
def sti_post_path(type = "post", post = nil, action = nil)
send "#{format_sti(action, type, post)}_path", post
end
def format_sti(action, type, post)
action || post ? "#{format_action(action)}#{type.underscore}" : "#{type.underscore.pluralize}"
end
def format_action(action)
action ? "#{action}_" : ""
end
Post index.html
<% #posts.each do |p| %>
<h2><%= p.title %></h2>
Created at: <%= p.created_at %><BR>
Created by: <%= p.user.name %><P>
<%= link_to 'Details', sti_post_path(p.type, p) %><P>
<% end %>
The error appears when I try to access index.html, and I haven't tried other links yet. I've tried removing 'underscore', then '_path' becomes an undefined method. I've also tried other suggestions such as 'gsub', but it also shows it as an undefined method, which leads me to think that it's a syntax error...
UPDATE:
I had attr_accessor :type and that made 'type' nil. So I removed that and now it is working
In your PostsHelper.rb
def format_sti(action, type, post)
action || post ? "#{format_action(action)}#{type.underscore}" : "#{type.underscore.pluralize}"
end
This method's else portion has type.underscore. type may be nil here. To verify it, try this:
def format_sti(action, type, post)
action || post ? "#{format_action(action)}#{type.underscore}" : "#{"post".underscore.pluralize}"
end
Try the try command, which will not return the NoMethodError exception and will return nil instead,
def format_sti(action, type, post)
action || post ? "#{format_action(action)}#{type.try(:underscore)}" : "#{type.try(:underscore).pluralize}"
end
Definition:
Using try, a NoMethodError exception will not be raised and nil will be returned instead, if the receiving object is a nil object or NilClass.
Here is the reference

Custom url helper method in presenter causing test error

I'm writing tests for a presenter class and am getting the following error when running them, coming from a custom url helper method.
Error:
PersonPresenterTest#test_0011_should get email icon:
ArgumentError: arguments passed to url_for can't be handled. Please require routes or provide your own implementation
app/helpers/people_helper.rb:4:in `link_fa_to'
app/presenters/base_presenter.rb:14:in `method_missing'
app/presenters/person_presenter.rb:54:in `email_icon'
test/presenters/person_presenter_test.rb:59:in `block in <class:PersonPresenterTest>'
person_presenter_test.rb
class PersonPresenterTest < ActionView::TestCase
add_template_helper(PeopleHelper)
def setup
#person = FactoryGirl.create(:person)
#presenter = PersonPresenter.new(#person, view)
end
test 'should get email icon' do
expected = '<a class="icon-link" href="/people/1"><i class="fa fa-envelope fa-1x"></i></a>'
actual = #presenter.email_icon
assert_equal(expected, actual)
end
end
person_presenter.rb
class PersonPresenter < BasePresenter
presents :person
def email_icon
link_fa_to('envelope fa-1x', person) if person.email.present?
end
end
base_presenter.rb
class BasePresenter
def initialize(object, template)
#object = object
#template = template
end
def self.presents(name)
define_method(name) do
#object
end
end
def method_missing(*args, &block)
#template.send(*args, &block)
end
end
people_helper.rb
module PeopleHelper
def link_fa_to(icon_name, link)
link_to content_tag(:i, '', class: "fa fa-#{icon_name}"), link, class: "icon-link"
end
end
routes.rb
Rails.application.routes.draw do
resources :organisations
resources :people
resources :reset_password, only: [:edit, :update, :new, :index, :create]
resources :dashboards, only: [:index]
resources :users
get 'profile' => 'users#show', as: :profile
controller :sessions do
get 'login' => :new
post 'login' => :create
end
get '/auth/:provider/callback', to: 'sessions#create'
get "sessions/create"
get 'sessions' => "sessions#destroy", as: :logout
root 'sessions#new'
end
I can test presenter methods which use link_to successfully, and would expect methods calling link_fa_to to 'fall' through to the template in the same way. This is only affecting tests, the method works perfectly when running the application.
Any help much appreciated.
edit:
If I remove add_template_helper(PeopleHelper) from person_presenter_test.rb, the error is:
Error:
PersonPresenterTest#test_0011_should get email icon:
NoMethodError: undefined method `link_fa_to' for #<#<Class:0x007fcdb6bb19e0>:0x007fcdb6bb15a8>
Did you mean? link_to
app/presenters/base_presenter.rb:14:in `method_missing'
app/presenters/person_presenter.rb:54:in `email_icon'
test/presenters/person_presenter_test.rb:58:in `block in <class:PersonPresenterTest>'
edit 2:
After updating people_helper.rb to the following in response to Shishir's answer, the error message remains the same:
module PeopleHelper
def link_fa_to(icon_name, link)
link_to link, class: "icon-link" do
content_tag(:i, '', class: "fa fa-#{icon_name}")
end
end
end
The method content_tag returns a string (actually it's an ActiveSupport::SafeBuffer, but you can handle it like a string), so that's not your problem.
It seems that you are calling your helper method with an instance of ActiveRecord::Base instead of an url:
link_fa_to('envelope fa-1x', person) if person.email.present?
vs:
def link_fa_to(icon_name, link)
link_to content_tag(:i, '', class: "fa fa-#{icon_name}"), link, class: "icon-link"
end
You could try to update your code to something like this:
link_fa_to('envelope fa-1x', person_path(person)) if person.email.present?
The syntax of link_to you are using doesn't accept content_tag as parameter. It only accepts string.
link_to content_tag(:i, '', class: "fa fa-#{icon_name}"), link, class: "icon-link"
Try
link_to link do
content_tag(:i, '', class: "fa fa-#{icon_name}")
end

The action 'create' could not be found for WatchedWatchersController

I've searched high and low for this and the other solutions don't seem to help.
The error:
The action 'create' could not be found for WatchedWatchersController
I get this after clicking a link made with this code in a view:
<%= link_to 'Watchlist', { :controller => "watched_watchers",
:action => "create",
:watcher_id => current_user.id,
:watched_id => user.id},
:method => "post" %>
My model for this class is:
class Watched_Watcher < ActiveRecord::Base
attr_accessible :watched_id, :watcher_id
validates :watched_id, :watcher_id, presence: true
end
And my controller is:
class WatchedWatchersController < ApplicationController
def new
end
def create
#ww = Watched_Watcher.new
#ww.watcher_id = params[:watcher_id]
#ww.watched_id = params[:watched_id]
#ww.save
end
def update
end
def edit
end
def destroy
end
def index
end
def show
end
end
I've set up my routes as a RESTful resource:
resources :watched_watchers
And rake routes reveals:
POST /watched_watchers(.:format) watched_watchers#create
So I'm stumped and any help is appreciated. Thanks in advance.
Vimsha's comment solved it
"Rename your model to WatchedWatcher(no underscore)". And then once I fixed the model name I just needed to have a redirect back to the same page.

Rails: Display user's liked post & own their posts on the same page

I'm fairly new to rails & I've been stuck on this problem for some hours. I am trying to display the posts the user has liked and the user's actual posts.
With my current code, I'm getting this error "undefined method `title' for #" and it's being extracted from this line: "<%= link_to post.title, post %>".
Coud anyone shed some light as to how I can get this to work? (more code below)
def show
#user = User.find_by_username(params[:id])
if #user
#posts = #user.posts.all + #user.likes.all
render actions: :show
#likes = #user.likes.all
else
render file: 'public/404', status: 404, formats: [:html]
end
end
Here's my routes file:
resources :likes, only: [:create, :destroy]
resources :posts
devise_scope :user do
get 'register', to: 'devise/registrations#new'
get 'edit', to: 'devise/registrations#edit'
get 'login', to: 'devise/sessions#new'
get 'logout', to: 'devise/sessions#destroy'
end
Here's the 'show' view:
<% if #posts %>
<% #posts.each do |post| %>
<%= link_to post.title, post %>
<% end %>
<% end %>
"<%= link_to post.title, post %> display <%= post.inspect %>" here's the results
<Post id: 11, title: "testing123", user_id: 2, created_at: "2013-05-18 19:25:45", updated_at: "2013-05-18 19:25:45"> #<Like id: 23, post_id: 10, user_id: 2, created_at: "2013-05-18 21:39:17", updated_at: "2013-05-18 21:39:17">
It works when I just use this -> #posts = #user.posts.all but the problem starts when I use this -> #posts = #user.posts.all + #user.likes.all
which gives me the "undefined method `title'" message..
You may want to add something to the user model...
class User < ActiveRecord::Base
has_many :likes
has_many :liked_posts, :through => :likes, :source => :post
...
end
Then, in your controller you can do this
#posts = #user.posts + #user.liked_posts
I think that in active record it will be faster than using ruby map
#posts = Post.joins("left join likes on likes.post_id = posts.id").
where("posts.user_id ? OR likes.user_id = ?", #user.id, #user.id)
Probably better will be to define scope in post model
scope :owned_or_liked_by, ->(user) { joins("left join likes on likes.post_id = posts.id").
where("posts.user_id ? OR likes.user_id = ?", user.id, user.id) }
And then you can use
#posts = Post.owned_or_liked_by(#user)
Other solutions will also work, but that generates you one sql query and it will be faster when you will have a lot amount of data.
It seems like #user.likes# doesn't return a Post related Array or ActiveRelation.
If assuming that a Like object has a post_id attribute, then you might want to modify the code as such:
#posts = #user.posts.all + #user.likes.map(&:post)
This is another approach you can take, a way to put it into one query and potentially sort. If you want to include it all in one list.
class Post < ActiveRecord::Base
def self.visible_to(user)
where('posts.user_id = :user_id or likes.user_id = :user_id', { :user_id => user.id}).includes(:likes).order('created_at desc')
end
end
Then in the controller, you'd do
#posts = Post.visible_to(#user)

Mongoid: undefined method `name' for nil:NilClass, even when it exists

When working with one-to-many relations in with Rails 3.1 and Mongoid, I keep bumping my head on undefined method `name' for nil:NilClass even when I'm positive it exists. Either it's a stupid mistake or then there's something wrong with Mongoid. Let's elaborate:
I keep getting this error:
NoMethodError in Leads#index
Showing /app/views/leads/index.html.haml where line #19 raised:
undefined method `heat' for nil:NilClass
Extracted source (around line #19):
16: - #leads.each do |lead|
17:
18: %tr
19: %td #{lead.visit.heat}°
20: %td
21: = link_to lead.name, :controller => "leads", :action => "show", :id => lead.id
And when I try to reproduce this in the console, it seems to work great. Truly mind-boggling..
Here's the code from relevant places:
-------------------------*SCHNIP*------------------------------------
class Company
include Mongoid::Document
include Mongoid::Timestamps
field :name, type: String
has_one :visit
def self.get_companies
visits = Visit.get_visits
companies = self.all
visits.each do |visit|
unless companies.name.include?(visit.name)
new_company = self.new
new_company.name = visit.name
new_company.visit = visit
new_company.save
end
end
#return companies for current instance
return Company.where(:visit.exists => true)
end
end
-------------------------*SCHNIP*------------------------------------
class Visit
include Mongoid::Document
include Mongoid::Timestamps
field :heat, type: Integer
field :name, type: String
belongs_to :company
def self.get_visits
return self.all
end
end
-------------------------*SCHNIP*------------------------------------
class LeadsController < ApplicationController
def index
#selected = 'visitors'
#leads = Company.get_companies
end
end
-------------------------*SCHNIP*------------------------------------
app/views/leads/index.html.haml
- #leads.each do |lead|
%tr
%td #{lead.visit.heat}°
%td
= link_to lead.name, :controller => "leads", :action => "show", :id => lead.id
-------------------------*SCHNIP*------------------------------------
I just ran into this, I had an Account -> Transaction relationship.
I embedded Transactions into Account, which then prevented me from making Transactions on their own. I got the same error message.
But if I did this:
a = Account.create
a.transactions.create
Then everything went fine. Hope that helps explain something.
Not the answer to your question but why do you have:
def self.get_visits
return self.all
end
In your Visit model is this not the same as calling Visit.all ?
When you call lead.name lead is nilclass it not a company as i guess you are expecting it to be.
It all seems a bit odd and far to much code for what you are trying to achieve.
I would go back to basics.
The error message you presented actually suggests that the lead in question has a Null lead.visit somewhere. You have a defined "lead", but its "visit" was not defined.
Are you sure that you can use .exists as in :visit.exists? It seems that you are receiving some leads which actually do not have that visit field.
To check, you could try something like
- #leads.each do |lead|
- if lead.visit
%tr
%td #{lead.visit.heat}°
%td
= link_to lead.name, :controller => "leads", :action => "show", :id => lead.id
Please check if this works.

Resources