cannot bring up show page - ruby-on-rails

This is the button that should bring up the show page
edit - changed
<%= button_to 'Show', post_path(p) %>
This does bring up a button but I get an error when I click it:
No route matches [POST] "/posts/3"
I am confused why a POST request is being sent. (Note "post_path" refers to a "Post" controller/model).
In my routes I have
resources :posts
The button is on the index page and I have an iterator to make an edit button for each Post.
Here is my "show" action:
def show
#post = Post.find(params[:id])
end
Thanks for your help.
*edit: the code is here: https://github.com/MaxPleaner/feature_tester*

Rails will construct a form around button elements so that they work properly, and forms by default will use method: :post.
If it's just a link to the show page, it should be a link. You can style the link to look like a button if you really wish.

Related

How to add a button in ActiveAdmin to create a new record for another resource, with fields pre-populated with values from the current resource?

In my ActiveAdmin dashboard, I have two resources - Posts and ScrapedPosts. For a ScrapedPost, I want to add a Publish Post button, which, when clicked, goes to a page for creating a new Post (new action), where all the fields for Post are pre-filled with values from ScrapedPost (Post and ScrapedPost have identical schema).
Here is my current code inside app/admin/scraped_post.rb
ActiveAdmin.register ScrapedPost do
action_item :view, only: :show do
link_to "Publish Post", new_admin_post_path
end
end
This adds a new button called Publish Post. When I click on it, as expected, it creates a page for adding a new Post. However, I want the fields pre-filled with the values from the current ScrapedPost from where I am creating the post.
I have tried a number of things so far. The documentation for action_item is very basic and it didn't help. It looks like I can't pass parameters to the action identified by new_admin_post_path. How can I do it?
[I started learning RoR just this week, so I'll be grateful if you can explain your solution as well.]
All action_item is doing is injecting a link styled as a button onto the show page. You can pass parameters to the link target by embedding them in the link. However, new does not accept parameters so to copy a Post what you need is a member_action:
member_action :clone do
resource.clone
render :new
end
This action can be invoked so:
action_item :clone, only: :show do
link_to "Publish Post", clone_admin_post_path
end
Make sure first that works for copying a Post. If you want to create a ScrapedPost from a Post then you will need to pass the id of the Post as a parameter:
link_to "Publish Post", clone_admin_scraped_post_path(post_id: resource.id)
then the ScrapedPost member action can find it:
member_action :clone do
#scraped_post = Post.find(params[:post_id]).clone.becomes(ScrapedPost)
render :new
end
As an aside, for better or worse ActiveAdmin is an additional layer of abstraction on top of Ruby on Rails so my recommendation is always to master vanilla Rails first to ease the learning curve.

How to prevent redirect after submitting data through a form

New to rails (programming as a whole), and I'm a little confused about routing.
I have a form in my view that takes someone's email, and then emails them once they hit submit. It works, but after I hit submit I'm being redirected to the view for the method I'm calling in order to mail the form. I don't want to be redirected, I want to stay on the same page. I have attempted using POST and PUT, but both redirect me. Am I using my controller incorrectly?
My controller has this method:
def mail
recipient_email = params[:email]
itinerary_body = params[:body]
x = ItineraryMailer.itinerary("#{recipient_email}", "#{itinerary_body}")
x.deliver
end
And here is the form from my view:
<%= form_tag({controller: "bookings", action: "mail"}, method: "post") do %>
<%= text_field_tag(:email) %>
<%= text_field_tag(:body) %>
<%= submit_tag("Email Me!") %>
My route:
match '/bookings', to: 'bookings#mail', via: 'post'
Thank you!
Since you don't have a redirect_to in your mail action Rails isn't redirecting you anywhere. Instead, it's just trying to render that action's view directly. However, I'm guessing that isn't the view you want rendered.
So, instead of trying to prevent a redirection (which isn't happening anyway) I would suggest that you take the opposite approach: use a redirection to get to the correct view. At the end of your mail action do this:
redirect_to action: :original_action_name
Where :original_action_name is the name of the action that gave you the view you want.
You could also use the render 'action' suggested in a comment, but that can cause problems in some cases where the current action may not have loaded or set up everything needed by the view you want to have rendered. Of course, you could just do that loading/setup in the current action but then you are doing the same thing in two places which isn't DRY.

update div in index view after calling update method in ajax in rails?

I have a page with list of posts and I use ajax for pagination using will_paginate and I have a "Like" button near by each post. If the user clicks the "Like" button then I need to update the count of likes in my table and I want to change the "Like" button to "Dislike".
Say, for example if I am in the second page of the post and I click on the "Like" button I would need to call my update method and how could I bring back to the same page and change the button using ajax.
I could possibly do if my update logic is in the same index method but how could I replace the content in the index.html.erb if my logic resides in the update method.
Please help me. Thanks.
Your question says:
Say, for example if I am in the second page of the post and I click on the "Like" button I would need to call my update method and how could I bring back to the same page and change the button using ajax.
Lets go through the steps one by one:
a. Create a route for your custom method where you'll update it and it has to be a post route since we want to send the post id which is to be updated
post '/update_post/:id' => "your_controller#update_post", as: :update_post
b. Create a link:
<%= link_to "Like", update_post_path(post.id),id: "post_#{post.id}",method: :post %>
c. Have a respond_to block in your method and update your post:
def update_post
#post = Post.find(params[:id])
# update your post here
respond_to do |format|
format.js{} #this will allow you to have update_post.js.erb in your view
end
end
d. Update your link in update.js.erb:
$("#post_<%= #post.id %>").text("Dislike");
Now since we are updating your link and post by ajax you will remain at same page and you wont have to worry about pagination. For more information refer to Working with javascript in rails

UJS - where do I put the js.erb?

My articles can appear on several sites, so as well as an article model with title, body etc and a site model with site_id, site_name etc, I have I have an article_site_permission model, with article_id, site_id and visible which can be either true or false.
On my article edit page, I've done a button_to:
<%= button_to 'Hide', article_site_permission_path(:id => #article_site_permission_id, :article_site_permission => {:visible => "false"}), :method => :put %>
This works - it changes the permission to false. And I can show the Show button which does the reverse.
Now I want to refresh the div that has the button in it by adding :remote => true to the button link. But where do I put my javascript?
Is it in the article_site_permission view - even though I'm looking at a view of the article itself?
Is it called update.js.erb?
Thanks for your help.
Update for clarity.
My button is on the articles/edit page. The button updates article_site_permissions. I want to go back to articles/edit and refresh the div that has the button in it.
I must edit the update controller for article_site_permissions, but where do I put the js to refresh the div?
In your controller, redirect to the action you want (index, show, etc.). Do a
respond_to do |format|
format.js
end
under that action in your controller. Then, in the corresponding view, have a file named
index.js.erb
Or replace index with whatever action, just be sure to give it the same name as the action that's calling it.
EDIT
I should also mention you are correct in adding the remote true to your button. It's hard to tell from your question what action you're trying to reach in which controller. If you're trying to access the show action of the ArticleSitePermission controller, you're doing well. However, it seems like you're not trying to route to show. Check out this link for more info on routing to different actions.
EDIT 2
This should do it.
<%= link_to 'Click me', {:controller => "article", :action => "update", :id => #article_site_permission_id },
:remote => true %>
Also, if all you want to do is redirect to the article, you don't need to do js. Just redirect to articles#show

Rails - display results of index and show actions via ajax

I have a very simple Post resource with two actions, index and show. My template contains a sidebar with links to each previous post. I want the sidebar links to display their content (i.e. the results of the "show" action) via ajax
I know there are lots of excellent tuts that show you how to create a form that submits with ajax but this time I want to use it to display the contents of my index and show actions without page referesh
. Are there any decent tutorials out there that give tips on how to do this?
I reckon I need to create a show.js.erb file, and tell my index action to respond to js but I'm a little bit stuck getting any further. I don't quite know what to put in controller's show action or show.js.erb - it's a little difficult to visualise what I need to do
PS - using rails 3.0.7, jquery-1.5
Got this working, it was very simple in the end.
Step 1 - add :remote => true to links in sidebar
#application.html.haml
%nav#sidebar
- for post in #posts
= link_to post.title, post_path, :remote => true
%div#main
= yield
Step 2 - tell your controller to respond to JS on the show action
def show
#post = Post.find(params[:id])
#posts=Post.all # needed for sidebar, probably better to use a cell for this
respond_to do |format|
format.html # show.html.erb
format.js # show.js.erb
end
end
Step 3 - Create _post.html.haml
# _post.html.haml
%article.post
= sanitize post.body
Step 4 - Create show.js.erb and replace the html in the #main div with the contents of the _post partial (that we created in step 3)
# show.js.erb
$("#main").html("<%= escape_javascript(render #post) %>");
Now all the content is passed via ajax and it's working fine.
I don't have a full answer at hand, because I'm relatively new to this, too.
But, I would start by taking a look at JQuery's get() method. You should be able to use that to call the index or show method. Those methods should return the html that you want to display in the non-sidebar section of the page. You can use get()'s callback handler to place that HTML into the appropriate div on the page.
Sorry that this is a little vague, but if you play with this I bet you'll figure it out.

Resources