How do I pass params to my devise_invitable controller? - ruby-on-rails

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.

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 %>

Creating a PUT request in 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 %>

Creating new model instance with paramethers (Rails)

I need to create new Event from User's guest page and the Event.visitor_id should be User.id
Event.rb
def create
#event = current_user.owner_events.new(event_params)
end
protected
def event_params
params.require(:event).permit(:visitor_id)
end
I need to correct the view below which is not working:
<%= link_to "Create event with this user", events_path(visitor_id: #user.id), method: :post %>
I get: ActionController::ParameterMissing in EventsController#create
Try that (you forgot to add event key):
<%= link_to "Create event with this user", events_path(event: { visitor_id: #user.id }), method: :post %>
For more details read 'strong parameters' gem documentation.
I just had to add .to_i to #user.id
<%= link_to "Create event", events_path(:event =>{:visitor_id => #user.id.to_i} ), :method => :post %>

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

link_to update (without form)

I want a link to update a resource, without using an HTML form.
Routes:
resources :users do
resources :friends
end
Rake routes:
user_friend GET /users/:user_id/friends/:id(.:format){:action=>"show", :controller=>"friends"}
PUT /users/:user_id/friends/:id(.:format){:action=>"update", :controller=>"friends"}
I want to use the put to update a friend by a simple link, something like this:
<%= link_to "Add as friend", user_friend_path(current_user, :method=>'put') %>
But when I click the link, it tries to go into the show action.
What is the right way to do this?
link_to "Add as friend", user_friend_path(current_user, #friend), :method=> :put
Will insert a link with attribute 'data-method' set to 'put', which will in turn be picked up by the rails javascript and turned into a form behind the scenes... I guess that's what you want.
You should consider using :post, since you are creating a new link between the two users, not updating it, it seems.
The problem is that you're specifying the method as a URL query param instead of as an option to the link_to method.
Here's one way that you can achieve what you're looking for:
<%= link_to "Add as friend", user_friend_path(current_user, friend), method: 'put' %>
# or more simply:
<%= link_to "Add as friend", [current_user, friend], method: 'put' %>
Another way of using the link_to helper to update model attributes is by passing query params. For example:
<%= link_to "Accept friend request", friend_request_path(friend_request, friend_request: { status: 'accepted' }), method: 'patch' %>
# or more simply:
<%= link_to "Accept friend request", [friend_request, { friend_request: { status: 'accepted' }}], method: 'patch' %>
That would make a request like this:
Started PATCH "/friend_requests/123?friend_request%5Bstatus%5D=accepted"
Processing by FriendRequestsController#update as
Parameters: {"friend_request"=>{"status"=>"accepted"}, "id"=>"123"}
Which you could handle in a controller action like this:
def update
#friend_request = current_user.friend_requests.find(params[:id])
#friend_request.update(params.require(:friend_request).permit(:status))
redirect_to friend_requests_path
end

Resources