Creating a form Ruby on Rails - ruby-on-rails

I'm trying to create a form on my website but I get this error:
undefined method 'model_name' for NilClass:Class
says the error is on line #33.
On line 33 I've got <%= form_for #try do |f| -%>

A view does not exist in isolation. You need to have your controller set up all the variables that you might need in the view.
So, assuming this is an edit view, you'll need to have code in your controller's edit action, something like this:
def edit
#try = SomeModel.find params[:id]
end
This will set up the #try variable and provide it to the view.

The #try variable must be nil. How is it set? Are you certain it will always contain a valid object?

You need to link your form to a specific model. In your controller, what code is defining #try? Whatever it is seems to be failing to specify a new or current model instance.

If you are using the code in new.html.haml or new.html.erb view file
def new
#try = ModelName.new
end

Related

Helper method with the same name as partial

I have a helper with a method named search_form like this:
module Admin::BaseHelper
def search_form(*args)
# my great code here
end
end
To call this method in my HAML code, I can do this:
= search_form
= search_form()
= search_form(param1: "value1", param2: "value2"...)
My problem is with this first call. When I do this in any HAML file, it renders my helper. Except if my file name is _search_form.html.haml. Is that case, it returns nil.
If I put a raise error in the helper, I notice that my method isn't being called, but I am not able to find what is being called and why.
If I use the syntax on the second and third lines, it works as expected by calling my helper method.
So my question is: is this standard Rails behavior or a bug?
By default, Rails will look for a local variable with the same name as your partial, which may conflict with existing method names.
One way to get around this is to simply redefine the method inside your partial:
<% search_form = self.search_form %>
# Rest of the partial's code

need to pass parameter from controller to .html.erb file

My controller code:
def description
product = #products.find(params(:id))
end
This is in the controller and I have to pass the product variable to description.html.erb. How can I do this?
It is giving me an ArgumentError in StoreController#description.
In general the way variables from the controller get passed to the views is by assigning them as an instance variable, which are variables defined with an # before it, e.g #products. If you want the product variable to be passed along, it has to be set as #product, like so:
#product = #products.find ...
In this particular case, you are getting an error raised before your view even is called. The only line in your controller action is throwing this.
Make sure that #products is actually being set. It's not being set in the #description method, so is it being set in a before_filter here? Is #products able to call #find? In Rails we often only see a model calling this method, e.g Product.find(params[:id]).
Further more, I see that you're accessing your params hash with regular brackets instead of square brackets. In Ruby you use square brackets. This alone may be what's causing the error. Try changing that to:
#product = #products.find(params[:id])
You can pass variables from controller to views using #
example in controller :
#my_var = 'toto'
in view
<%= #my_var %>

Extra instance variable in controller is nil in view?

I have been searching through Stack Overflow for a few hours now, but none of the related questions seem to apply to my issue.
I am new to Rails, with this being my first real project, and I may be confusing the MVC setup a little. I am attempting to assign the #stars instance variable while in an action of the searches_controller.rb:
def create
#search = Search.new(params[:search])
tempstr = searchstr(#search)
#stars = Star.where("tempstr", :limit => 100)
end
#search is created fine, being a complex search with varying parameters. tempstr is just a simple string container for the results of searchstr(#search), which is a quick method for converting the search parameters into a MySql-relevant string (which seems to be easier than trying to use the .where helper normally, in this case). I'm sure I can just put searchstr(#search) directly into the .where, but I split them up for now so I can inspect the elements as they pass through.
Anyways, the issue comes up when I try to call #stars in the show.html.erb view. Even with something as simple as this:
<% #stars.each do |star| %>
<%= display stuff %>
<% end %>
I get an error saying 'each' is not a method of nil:NilClass. So, I changed it to the following to see if #stars was nil:
<%= #stars.inspect %>
Sure enough, #stars is nil. However, when I add this line to my controller to check #stars there:
return render #stars.each
I see that the variable is filled with the correct star objects from the Star.where(), just as I had intended. A quick .inspect shows the variable is not nil, when in the controller.
So, I am unsure why the view is receiving it as nil if it has been defined in the controller just fine. I wouldn't be surprised if it was me misunderstanding how MVC works, though. The Star class was defined in the Star model, but maybe it is because I am trying to access it from the Searches controller, and thus it isn't initialized for the view?
Should I be going about doing this some other way? I attempted to use a local variable (using stars instead of #stars), but then the view says "Undefined local variable or method 'stars'".
Any help would be much appreciated, I have already wracked my brain for hours creating the complex search and parsing the star file data into the database, so I'm a bit burnt out. I can supply more information if requested, I'm not sure what else would be helpful in providing an answer.
You are setting #stars in the create method, but the view you are talking about is show.html.erb. Try setting #stars in the show method too. Something like this:
def show
#search = Search.find(params[:id])
tempstr = searchstr(#search)
#stars = Star.where("tempstr", :limit => 100)
end
If this does not help you, please show the rest of you controller actions, so we can help you better.

Using rails helper method

I've found a helper method that I would like to use to resize embedded videos on my site. I've tried using this method several ways but received multiple undefined method errors. Here's the method:
def resize_video(new_width,new_height)
width,height = embed_code.match(/width=.?(\d+).*height=.?(\d+)/).to_a.drop(1)
embed_code.gsub(width,new_width).gsub(height,new_height)
end
I would like to apply this method to the <%= raw link.embed_code %> portion of my view, available HERE, to change the width and height to the desired values. Where should I put the method and how should it be called?
Update
Per Karel's advice, I put the method in links_helper.rb and used <%= raw (link.embed_code).resize_video %> in the view but received this error undefined method resize_video for #<String:0x492bf40>
I would suggest you to put the helper method in the corresponding helper of the view(ie. if the view file belongs a controller xyz, there should be a helper with name xyz_helper). This is the rails convention. If the helper method is used in multiple controller views, we can put it in application_helper.
If you are getting undefined method for embed_code, we have to pass that variable as follows
<%= raw resize_video(link.embed_code, width, height) %>
def resize_video(embed_code, new_width, new_height)
width,height = embed_code.match(/width=.?(\d+).*height=.?(\d+)/).to_a.drop(1)
embed_code.gsub(width,new_width).gsub(height,new_height)
end
Place your helper methods in a file name video_helper.rb in helpers folder. More here.

Passing a model attribute to a Rails view using redirect_to

I'm trying to pass a model attribute to a view, after successfully setting it to a new value from inside an action in my controller. But this variable is always nil by the time it gets to the view, so I can't use it to conditionally display stuff. I should add that this attribute is not a field in the database. What am I missing/doing wrong?
Here is the code in my model:
attr_accessor :mode
#getter
def mode
#mode
end
#setter
def mode=(val)
#mode = val
end
...in the controller:
#report.mode = "t"
redirect_to edit_report_path(#report)
...and in my view:
<%= build_report(#report.mode) %>
...but this helper method never gets the variable I just set in the controller. It is nil. What gives? Clearly I'm missing something basic here because this seems like it should be straightforward. Any insight would be greatly appreciated.
Thanks.
edit_report_path generates a URL with the ID of #report in it.
redirect_to essentially creates a whole new request, and goes to that URL. When it gets to edit, all it has is the ID. Usually that's fine - it looks up the object and keeps going, but of course it's not going to have the non-db field you set.
There are a couple ways to fix this. You can use :render instead to get to the edit page - then #report will have the field set.
#report.mode = "t"
render :action => edit and return
Or, you can make mode a database field.
The problem here is in the redirect_to. When you redirect somewhere else all instance variables are lost. So when you set #report.mode = "t" it sets the attribute. But when you redirect that data is lost.
I am assuming the <%= build_report(#report.mode) %> is in edit_report.html.erb and the code from when you set 'mode' is not in the edit action. If this is the case you may be able to pass the report.mode to the edit action in the url like so:
build_report(#report.mode, :mode => "t")
The problem is the redirect_to; you're returning a response to the client that causes it to redo the request with a different url. In that second request the mode isn't set because you didn't save it before wrapping up the first request.

Resources