Rails asking for "end", but everything has an end? - ruby-on-rails

Ok, so I am trying to learn Rails by watching YouTube; so far I am having a better understanding as I go along.
Problem is, I am using Rails 4 whereas the vidoe uses Rails 3. No big deal. There was a problem with the video's code, so someone posted in the comments section some corrected code.
Problem is, I get this error:
SyntaxError in PostsController#create
/home/chris/blog/app/controllers/posts_controller.rb:43: syntax error, unexpected end-of-input, expecting keyword_end
Now I've gone through my code, looked it all over, and from what I do know of Rails so far, everything has an appropriate end. I have used comments and, for every beginning, there is an 'end'. But I have definitely messed something up. And yes this is Rails 4.0 I am using.
class PostsController < ApplicationController#main
def index#1
#posts=Post.all
end#1
def create#2
#post=Post.new(post_params)
if #post.save#2.1
redirect_to posts_path, :notice =>"Your post was successfully saved"
else
render "new"
end#2.1
end#2
def new#3
#post=Post.new
end#3
def edit#4
end#4
def show#5
#post=Post.find(params[:id])
end#5
def update#6
end#6
def destroy#7
end#7
private
def post_params#1
#allow = [:title, :content]
params.require(:post).permit(#allow)
end#1
end#main

There seems to be a stealth byte order mark character between end# and #1 near the end. Here's how it looks on my editor:
Deleting that line and typing it again fixed it for me.

Related

Dot causing error in rails

I have a routes like this :
get ':user_name', to: 'profile#show', as: :profile
And the show method looks like this
before_action :set_user
def show
#posts = #user.posts.order('created_at DESC')
end
def set_user
#user = User.find_by(user_name: params[:user_name])
end
Everything seems fine . Like
If i go to localhost/hello its works.
But if i go to localhost/hello.world it gives error and says that undefined method posts for nil:NilClass And it also says
Parameters:
{"user_name"=>"hello",
"format"=>"world"}
But we know user_name should be hello.world
Then why is this error ?? :(
Clearly I think this line is creating problem
#user = User.find_by(user_name: params[:user_name])
How to fix it :( really annoying problem :(
This is a combination of two problems:
You are using find_by instead of find_by!. The normal version won't raise an ActiveRecord::RecordNotFoundException when it can't find the record, which would gracefully make rails respond with a 404 and aport the before_action, which means #user ends up set to nil, and so you can't call .posts on it.
As #davidwessman has pointed out in the comments, you can't use dots by default on Rails routes. I suspect you have a record with name hello.world, but it's trying to find just hello and so it can't find anything.

uninitialized constant UrlsController::Url

I'm new to Ruby and Rails, coming from Java and Playframework.
I'm following a tutorial http://www.sitepoint.com/building-your-first-rails-application-views-and-controllers/
I am getting an error on the line #shortened_url = Url.new
The error is :
NameError in UrlsController#new
uninitialized constant UrlsController::Url
I feel this is something like a ClassNotFoundError in Java ?? not sure ... does anyone know what I have to do. Is it basically a matter of using include or require, with the correct reference.
Apologies for the total newb question but I find it much easier to learn by doing and making mistakes, it sticks - and I reckon others will benefit too.
class UrlsController < ApplicationController
def new
#shortened_url = Url.new
end
def create
#shortened_url = Url.new(params[:url])
if #shortened_url.save
flash[:shortened_id] = #shortened_url.id
redirect_to new_url_url
else
render :action => "new"
end
end
def show
#shortened_url = Url.find(params[:id])
redirect_to #shortened_url.url
end
end
May or may not be the issue you're having, but Url is a reserved word in Rails.
Source: http://bparanj.blogspot.co.uk/2011/07/reserved-words-in-rails.html
Alternatively, it's weird that calling Url.new is calling new on your UrlsController instead of the Url model. This backs up my idea about using reserved words, it can often cause strange behaviour.
Edit: Oh and it looks like from another comment that you don't have a Url model. You'll need one of those before you can called .new on it. That said, don't create a model called Url, the reserved word thing will probably come back to bite you.

Rails 404 error for html format, but no issue with json format

This is puzzling me. I have a Rails application which, in production on Heroku, is returning 404 errors for many records, when requested as follows:
https://myapplication.heroku.com/records/500
The page you were looking for doesn't exist.
while the JSON version of the same page is fine:
https://myapplication.heroku.com/records/500.json
There are a few instances of model that work just fine with the regular HTML version:
https://myapplication.heroku.com/records/600
Here is the relevant part of config/routes.rb:
resources :records do
member do
get 'revisions'
end
end
And here is the #show action of the records controller:
# GET /records/1
# GET /records/1.json
def show
#r = Record.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #r }
end
end
This was all working fine yesterday, but today I did some database migrations on the records table and a lot of other changes to records. What's puzzling me is that the JSON part works, and the records do exist. I even tried adding the following to routes.rb and moving it to the top of the file:
get 'records/:id', to: 'records#show', constraints: { :id => /\d/ }
But it did nothing. Appending .html to the GET request in URL bar does not do anything either.
Any ideas would be greatly appreciated!
Edit: Here is a gist with the Heroku log.
Firstly, I would refactor your controller, like so:
#app/controllers/records_controller.rb
respond_to :html, :json
def show
#r = Record.find params[:id]
respond_with #r
end
Your code looks fine to me.... So I would suggest we take a deeper look into (asking some comments):
This was all working fine yesterday, but today I did some database
migrations on the records table
I was using PaperTrail for Versions and in the view for Record called User.find(#r.versions.last.whodunnit.to_i), but #r.versions.last.whodunnit.to_i was 0 and the user could not be found.
I was thrown by the 404 error because I thought it was somehow not finding the primary Record record in the database, when it was actually something else.
After enabling logging, this was not hard to debug. (I thought I had enabled logging before, but apparently not.)
Thank you all for your help!

Cached Controller Method?

I'm trying to make some changes to the show method in my events controller and noticed the changes making zero difference. I commented out the #event = Event.find_by_slug(params[:slug]) line and the show view still works and does not produce an error! I even deleted the entire show method and it still works. I thought for a moment I was working on a copy of the app, but it's definitely the correct one.
I've never had this problem before, but did recently upgrade my Rails version from 3.2.0 to 3.2.13. Wondering if there's a caching setting somewhere that's causing this. Has anyone experienced similar or got any pointers on where to look for a caching config setting perhaps?
EDIT - Code added
def show
#event = Event.find_by_slug(params[:slug])
#meta_title = "#{#event.headline} at #{#event.venue.name}, #{#event.venue.town} - #{#event.event_date.to_date.to_formatted_s(:my_format)}"
#meta_description = "#{#event.info.to_s.truncate(380, :separator => " ")}"
#facebook_image = "#{#event.event_image.url(:large)}"
respond_to do |format|
format.html # show.html.erb
format.json { render :json => #event }
end
end
The view is quite large, but I would call fields using something like this:
<h2><%= #event.headline %> TEST</h2>
'TEST' is something I just added to see if that would be rendered and it is, so i'm definitely editing the correct version of the app.
EDIT - New development in finding this bug
After extensive searches for dupe actions etc I gradually started trying to manually find the cause. First by scaffolding a new model and seeing if the same behaviour occurred and it didn't. Then looking at what was different, top to bottom in my event controller I started to comment out lines/actions and then test behaviour. Anyway, commenting out load_and_authorize_resource which I am using to call the CanCan gem and it's ability model the caused my app to behave as it should do, obviously now without my role based code.
Can anyone think why CanCan could be causing this?
CanCan have both load_resource, authorize_resource and load_and_authorize_resource. They all do what they say, so in your example will load_resource set the #event instance variable #event = Event.find(params[:id]). authorize_resource will just call authorize! #event before each action. load_and_authorize_resource will fist load the resource and then authorize as before.
Here is another example from the CanCan documentation on github:
class ArticlesController < ApplicationController
load_and_authorize_resource
def show
# #article is already loaded and authorized
end
end

Rails Brakeman warning: Dynamic Render Path false alarm?

I'm just getting started with Rails, so I'm using Brakeman to learn about potential vulnerabilities in my newbie code. It's throwing a high-confidence "Dynamic Render Path" warning about the following code in my show.js.erb file:
$('#media-fragment').html('<%= escape_javascript(render(params[:partial])) %>');
I actually expected this was a problem, so no surprise there. So I changed it to the following:
# controller:
def show
if legal_partial?
#allowed_partial = params[:partial]
else
raise StandardError, "unexpected partial request: #{params[:partial]}"
end
end
private
def legal_partial?
%w(screenshots video updates).include? params[:partial]
end
# ...
# show.js.erb
$('#media-fragment').html('<%= escape_javascript(render(#allowed_partial)) %>');
Although I believe the code is now safe, Brakeman is still unhappy with this. Is there a more idiomatic way to control rendering of a partial based on user input?
Update (2/5/2016):
This has been fixed as of Brakeman 3.0.3.
If the legal_partial? method is inlined like this:
def show
if %w(screenshots video updates).include? params[:partial]
#allowed_partial = params[:partial]
else
raise StandardError, "unexpected partial request: #{params[:partial]}"
end
end
Brakeman will be able to detect the guard condition and will no longer warn about the later render call.
Original answer:
Unfortunately, Brakeman does not know that if legal_partial? is a proper guard. All it knows is that params[:partial] is assigned to #allowed_partial, and that is then passed to render.
You may be able to tell that #allowed_partial will always be a safe value. At that point, you have to consider whether or not it makes sense to add complexity in order to make a tool happy.
Just as an example, you could do this:
def show
render_allowed_partial params[:partial]
end
def render_allowed_partial name
if %w(screenshots video updates).include? name
#allowed_partial = name
else
raise StandardError, "unexpected partial request: #{params[:partial]}"
end
end
It's basically the same thing, except now you are hiding the assignment of #allowed_partial from Brakeman.
(Warning: Not necessarily "best" way of doing this.)
Using brakeman 4.2.0
I had a similar issue trying to render a specific hand-positioned-and-named template. Every product of my app required that specific named template. The template name came from the controller params as params[:a_particular_slug].underscore.
I solved with something like this:
def show
if #products = Product.where(a_slug: params[:a_particular_slug])
render template: lookup_context.find(params[:a_particular_slug].underscore, ["featured_products"])
else
render_404
end
end
Here I'm looking for a template. If you need to use a partial, be aware that lookup_context.find third params set to true allows to search for partials.
You can find more about lookup_context.find here
Hope this helps.

Resources