Checking Data from a Controller on Button Click? - ruby-on-rails

I'm new to Ruby, but I have created a quiz-like site where users answer multiple-choice questions. Each question is assigned to a particular quiz, so there could be multiple questions for each quiz. I'm stumped at trying to see whether the choice selected is correct for that answer or not. All the answers were saved with a question_id referrer and a correct boolean.
I have a feeling it has something to do with link_to, but I can't figure it out.
Here is the controller I am accessing:
def check
puts "//////// //////// /////// #{#givenAnswer}"
puts "//////// //////// /////// #{#correctAnswer}"
end
Here is as near as I can get to making it work, but I get a Url error:
<%= link_to "#{#ans.content}", {:controller=>:pages,:action=>:check, :givenAnswer=>#ans.content, :correctAnswer=>params["correct#{#q.id}"]}, :method=>:get, :class => "btn" %>
The above gives a UrlGenerationError.
Both #q and #ans are created by loops in the script. They are defined properly.
Any help would be appreciated. Thanks!

As per syntax given by you for link_to you are missing closing '}' before :method option.
As long as pages controller is not under some namespace then it should generate the correct link and should not give url error.
In check action correctAnswer and givenAnswer will be available in params hash and not directly as #givenAnswer and #correctAnswer. Please see params hash in check action.

Related

Passing param using link_to and UJS

I'm having a hard time understanding the proper way to pass a param using link_to and UJS.
I have the following resources:
Photos
Comments
Users
A user is trying to comment on a photo by clicking "Add Comment." When this happens a box pops up using UJS showing a form rendered by utilizing a new.js.erb file. After "Create Comment" is posted the create.js.erb file is called to handle the update, which just hides the comment box and adds the comment to a list of comments.
In my index.html.erb for my photos I am doing the following:
I specify a link to add comments passing in the id of the current photo.
<%= link_to 'Add Comment', new_comment_path( photo_id: photo.id ), remote: true %>
This gives me the url: 0.0.0.0:3000/comments/new?photo_id=1, which is what I expect.
Now my question is, how do I handle this passed parameter in my new action such that I can specify something like
#comment.photo_id = photo_id
or
#comment.photo_id = params[:photo_id]
in my comments_controller.rb?
Is there something I can do in JS that will help me save the photo_id value to my #comment.photo_id column for the comment added?
First of all I'll suggest you to start using nested routes for things like comments or likes. You will find the railscast here nested_routes_railscast
Coming back to your question, use #comment.photo_id = params[:photo_id] in your controller.
There is a better approach to accomplish this, You can have the popup already on the photo show page. In the popup you can have a form for new comment model. After clicking on the specific photo you just have get the id of that photo using javascript and copy it into the hidden field for :photo_id in the form.
Yes, you can get photo_id in params, they way you have specified.
Suppose Photo has many comments in your case.
So in your case when in you get params[:photo_id] in comments_controller
you can do:-
#photo = Photo.find_by_id(params[:photo_id])
#photo.comments.create(params[:comment])
Please read about nested resources from guides.rubyonrails.org, so you can generate create comments route in restful manner.

Using Redirection in New Action in Rails 3

I am trying to construct my first new action in rails, thanks to the help of people here I have now got the vast majority working, but due to my mis-understanding of exactly how things work the action is not performing the desired action.
I have a database called Items, which contains :id, :external_url and :click_count
My goal is to have a link which when clicked on, the user is directed to the external url and :click_count is incremented by 1.
As it stands, I have the following:
view
<%= link_to image_tag( item.picture.to_s + ".gif"), items_clickcountplusone_path(:id => item.id)%>
items_controller
def clickcountplusone
clickeditem = Item.find(params[:id])
redirect_to clickeditem.external_url if clickeditem.update_attribute(:click_count, clickeditem.click_count + 1)
end
routes.rb
get 'items/:id' => 'items#clickcountplusone', :as => :items_clickcountplusone
Using this code, the page itself loads with all the links visible.
However, when I click on a link I get directed to items/whateveridiclickedon NOT the external URL and furthermore the :click_count value does not increase from its initial value.
Am I doing this correctly? In particular is the routes line ok, it currently appears as though i am instructing it to be directed to a specific page on my site for the item, which was not my intention... Also, what is wrong with the if statement meaning the count doesn't increase?
Many thanks for your patience
The mapped route "items/:id" is already associated with the show action and have precedence.
Try associating it with another URL.
get 'items/:id/visit' => 'items#visit', :as => :items_visit

New to Rails: How to pass arguments from a textbox to another controller?

I am new to Rails and don't quite understand what I'm supposed to do. Let's say, for example, I want a textbox containing a string to be passed into another controller (another page?) when the user clicks a button. How would I go about doing that?
Functions of controllers are pages, correct? Can a function take parameters just like a normal method? (E.g. sum(x,y))
For complete information, check out Rails Form helpers. Basically, you give the form_tag method a path which points to the controller and the action that you want to handle the form submission. For example,
<%= form_tag(search_path, :method => "get") do %>
<%= label_tag(:q, "Search for:") %>
<%= text_field_tag(:q) %>
<%= submit_tag("Search") %>
<% end %>
Here, the action and controller that search_path points to (defined in your routes) will receive the form submission and the value from the text field.
Your action in the controller IS a function, but it will not receive the value from the form submission as a parameter to the function. Instead, you will access it through the params hash. In the example above, you can access the value from the text field as
params[:q]
What are you doing with the string? Storing it? Using it as a parameter on another page?
I suggest you take a look at the Getting Started Guide, go through it, and pay particular attention to the What is Rails? section, where it explains MVC architecture and REST (Representational State Transfer.)
There are dozens of other Rails tutuorials out there, I'm sure if you searched this site you'd find many questions like this one:
https://stackoverflow.com/questions/2794297/how-to-learn-ruby-on-rails-as-a-complete-programming-beginner
Functions of controllers are pages, correct? Can a function take parameters just like a normal method?
Functions of controllers are pages if that's the route you've set up in your routes.rb configuration file. I suggest you run through some tutorials to understand what Rails is for and how it works.

Hard coding routes in Rails

Let's say I have this:
<%= link_to "My Big Link", page_path(:id => 4) %>
And in my page.rb I want to show urls by their permalink so I use the standard:
def to_param
"#{id}-#{title.parameterize}"
end
Now when I click "My Big Link" it takes me to the correct page, but the url in the address bar does not display the desired permalink. Instead it just shows the standard:
wwww.mysite.com/pages/4
Is this because I hard-coded an id into the page_path? It also does not work if I use straight html like..
My Big Link
I would appreciate it if anyone could verify this same behavior and let me know if this intended or not. I need the ability to hard code :id's to specify exact pages...
Just use page_path(page). I guess the path helpers don't access the database themself (which is good), but if they are being supplied with an object and that object has a to_param method this method is being used to generate an identifier.
<%= link_to "My Big Link", page_path(page) %>
It's because you are specifying the id:
page_path(:id => 4)
You could specify the path you want in this method:
page_path(:id => "#{id}-#{title.parameterize}")
Where have you defined the to_param method? In the model?
UPDATE TO MY QUESTION ---------------------->
Thanks all for the answers. This was kind of a one off situation. My solution was to simply go with html:
My Big Link
Which produced the desired:
wwww.mysite.com/pages/4-great-title-here
I didn't want to loop through page objects and waste a call to the database for this one link. Much appreciated for all the answers though!

Send querystring params as part of form post

Is there a way to capture the querystring and send that along as part of a form post? I'm using Rails 2.3.5 and my user is on a page that has multiple querystring parameters. On this page, they are going to submit a form. Inside the action that receives the post, I want to know what those querystring parameters were. Obviously, they are not sent as part of the post. So I need the actual form values, plus the querystring params that were on the page when the user submitted the form.
I'm sure I could write some nasty javascript that would shove the querystring params into hidden fields on the form so they would be available, but that seems ugly. My Googling hasn't turned up much, which makes me wonder if I'm just going about this all wrong. To make matters worse, I'm a Rails newbie.
Appreciate any pointers or ideas to get me going in the right direction.
A friend of mine showed me what I believe is an easier way:
<% form_tag params.merge(:action=>"someAction") do %>
Merging params into the hash necessary for making the form_tag did the trick perfectly.
The preferred way would be to use hidden fields. I haven't tried it, but I think you can specify additional query string parameters within the *_path or *_url helpers. Something like:
<% form_for(#post,
:url => post_path(#post, :foo => 'foo', :bar => 'bar')) do |f| %>
...
<% end %>
<% form_tag params.merge(:action=>"someAction") do %>
- No route matches [POST]
Use hidden_field_tag if you're using a GET request.
In our case we were using a simple form with a select for setting the Per Page values for pagination. We found that any existing GET params were cleared when submitting this form. To fix this we used hidden_field_tags in our form.
Inside of your form, just set hidden_field_tags for the existing GET params, like so:
form_content = request.query_parameters.collect do |key, value|
hidden_field_tag key, value
end
This will ensure that your existing params persist.

Resources