Creating a PUT request in Ruby on Rails? - ruby-on-rails

I want to be able to use a PUT request to edit the title of a song I uploaded in my Ruby on Rails application.
def update
#sound_byte = SoundByte.find(params[:id]) #Error here
#sound_byte.update!(sound_byte_params)
flash[:success] = "The soundbyte title was changed."
redirect_to sound_byte_path
end
private
def sound_byte_params
params.require(:sound_byte).permit(:mpeg, :mpeg_file_name)
end
I end up getting an error like this:
Couldn't find SoundByte with 'id'=song_name
Any ideas of how to fix this issue? I am using the Paperclip gem to enable the audio/mpeg file uploads.
EDIT: Here is my views code
<%= link_to "Edit", sound_byte_path(sound_byte.mpeg_file_name), class: "btn btn-primary btn-lg btn-xlarge", :method => :put %>

In the view page, you pass string sound_byte.mpeg_file_name as params, but in your controller, you use id #sound_byte = SoundByte.find(params[:id]).
Try this
<%= link_to "Edit", sound_byte_path(sound_byte.id), class: "btn btn-primary btn-lg btn-xlarge", :method => :put %>

Related

Rails parameters contain backslashes

I am currently working with button_tag to create a remote styled answer submission quiz. When pressing this button, instead of posting the new record, it is throwing an error.
ActiveRecord::RecordNotFound (Couldn't find Answer without an ID):
When looking at the server logs I see it is trying to work with these params when trying to post Parameters: {"{\"answer_id\":59}"=>nil, "id"=>"15"}
What I am looking, or expecting to see is this.
Parameters: {"answer_id"=>"59", "id"=>"15"}
Here is the button_tag I am using.
<% #question.answers.each do |answer| %>
<%= button_tag "#{answer.answer.titleize}", class: 'btn btn-block btn-lg btn-primary', data: {
remote: true,
method: :post,
url: answer_question_path(#question),
params: { answer_id: answer.id }
} %>
<% end %>
Here is my response controller which is responsible for submitting the POST request.
class ResponsesController < ApplicationController
def answer
question = Question.find(params[:id])
answer = question.answers.find(params[:answer_id])
response = question.responses.find_or_initialize_by(user: current_user)
if response.update(answer: answer)
head :ok
else
puts 'Something went wrong chief'
end
end
private
def responses_params
params.require(:response).permit(:user_id, :question_id, :answer_id)
end
end
I have tried using to_json on the parameter with no success and have not been able to find any solution elsewhere on SO or other forums. Any ideas?
This seems to be an issue with button_tag in the feature I am using it for.
button_tag creates a button element that defines a submit button, resetbutton or a generic button which can be used in JavaScript. button_tag is also an action view helper but is defined as a FormTagHelper.
button_to generates a form containing a single button that submits to the URL created by the set of options. button_to is a UrlHelper while button_tag is a ViewHelper.
Below is the button_tag code I was using which was creating the issue described above. Using button_tag fixed my parameters issue and also looks a bit cleaner. I hope this helps anybody else having issues with button_tag in the future.
<%= button_tag "#{answer.answer.titleize}", class: 'btn btn-block btn-lg btn-primary', data: {
remote: true,
method: :post,
url: answer_question_path(#question),
params: { answer_id: answer.id }
} %>
<%= button_to "#{answer.answer.titleize}",
answer_question_path(#question),
class: 'btn btn-block btn-lg btn-primary',
params: { answer_id: answer.id },
remote: true %>

How do I pass params to my devise_invitable controller?

I have created an invitation controller that is quite vanilla:
class InvitationsController < Devise::InvitationsController
def new
binding.pry
end
end
And I created a link that triggers that request like so:
<%= link_to "Invite #{#profile.name}", new_user_invitation_path(email: #profile.email), class: "btn btn-xs btn-primary" %>
The issue I am having is that when I get thrown into pry in that action, it doesn't show me that email parameter.
> params
=> <ActionController::Parameters {"controller"=>"invitations", "action"=>"new"} permitted: false>
How can I send params with that InvitationsControler#New action?
It turns out that new_user_invitation_path corresponds to a GET request to a new invitation object, which generates a new form.
The solution is to create another action in another controller then simply call it with a method: :post like so:
<%= link_to "Invite #{#profile.name}", invite_path(#profile), method: :post, data: { confirm: "Are you SURE you are ready to invite #{#profile.name}?"}, class: "btn btn-xs btn-primary" %>
That works like a charm.

Using a controller action on a button click - Rails

Really new to using Ruby on Rails and programming in gentle so apologies in advance if this seems very basic.
I'm working on a very simple wiki based website, where users can upgrade and downgrade their account.
In my downgrade.html.erb I have the following code:
<p>Are you sure you want to downgrade back to standard?<p>
<%= link_to "Yes", :controller => :charges, :action => :downgrade1, class: 'btn btn-danger' %>
<%= link_to "No", root_url, class: 'btn btn-success' %>
and in my charges_controller.rb I have my downgrade1 method:
def downgrade1
if current_user.premium?
current_user.update_attribute(:role, 'standard')
flash[:success] = "You have been downgraded to standard."
redirect_to root_url
else
false
end
end
Ultimately, when the user clicks that 'Yes' button, I want that downgrade1 method to run and the user's account to be downgraded back to standard.
However, what happens is the website loads a 'show webpage' with my header and footer, but the user is still a premium user.
Any ideas how I can fix this?
Thanks for your attempts to solve my problem, both your answers eventually led to me finding the solution.
In the end, I used this code in my view:
<%= button_to "Yes", { :controller => "charges", :action => "downgrade1"}, class: 'btn btn-danger' %>
and added this to my routes.rb
post "charges/downgrade1" => "charges#downgrade1"
Downgrading now works as planned.
Thanks again for your help.
I think the problem here is that you didn't specify the HTTP method for your link_to, like
<%= link_to "Yes", :controller => :charges, :action => :downgrade1, class: 'btn btn-danger', :method => :patch %>
By default, it will call a GET method, then nothing in your database will be changed.
And make sure you have defined that method in your routes.rb
You are missing one closing tag at the end of your if - else statement:
else
false
end
end

Responding with js in Rails

We have a link_to sending an ajax post, and are wondering if there's a way to change the content of the sending tag.
We basically want to update the database, then change the icon in the link_to block.
<%= link_to add_favorite_path({type: type, id: id}),
type:"button", disable_with: '...', :method => :post,
:remote => true, class: 'btn btn-default btn-sm', id: "#{type}-#{id}" do %>
<i class="fa fa-plus"></i>
<% end %>
Here's the favorites contoller:
class FavoritesController < ApplicationController
respond_to :js
def add
#type = params[:type]
#id = params[:id]
#selector = "#{#type}-#{#id}"
end
end
EDIT: add.js.erb:
var link = $("a#<%= #selector %>");
link.html('<i class="fa fa-check"></i>');
Found Solution:
Could not alter the item html when using the disable_with: option. Removed it and it works.
You can just make sure the appropriate controller reponds to JS
respond_to :js, :html
Then create the view file add.js.erb to add the appropriate JS to render the new icon.
I would like to see more code but something like this
$("#id_of_link").html("<i class='fa fa-check'></i>");
Although, I usually create partials and escape_javascript to render the new partial in the JS

Adding a create comment page

Rails beginner here. I'm having trouble with commenting on posts. I have the comments working when they are on the same page as the post but after trying to set up seperate pages for creating and viewing the comments i get the following error:
No route matches {:action=>"new", :controller=>"comments", :id=>"27"} missing required
keys: [:post_id]
My posts/show.html.erb file: (the second line is the link that's causing the problem)
<h class="eventhead"><%= #post.description %></h>
<%= link_to "Add comment", new_post_comment_path, class: "btn btn-primary btn-medium" %>
And here's my comments/_form.html.erb file:
<%= simple_form_for [#post, Comment.new] do |f| %>
<p>
<%= f.input :title, :subtitle, :body, :label => "New Comment", as: :text, input_html: {
rows: "3" } %>
</p>
<p><%= f.submit "Add Comment", class: "btn btn-primary" %></p>
<% end %>
Thanks for the help!
You are using a nested resource, so this requires that you pass in the post_id to the link_to. Revise your code as:
<%= link_to "Add comment", new_post_comment_path(#post), class: "btn btn-primary btn-medium" %>
Just as #jaycode mentioned you will need to make sure the comment#new action assigns #postin your controller.
# comments_controller.rb
def new
#post = Post.find params[:post_id]
#comment = Comment.new
end
Welcome to Rails :)
Check the content of method new_post_comment_path. Most likely it requires :post_id variable to be passed into it.
Perhaps you should use this instead:
And make sure in comments_controller.rb action new (def new in that file), you have #post_id variable defined.

Resources