I'm using a gem called mailboxer to allow users to send messages between each other.
In my controller:
def mailbox
#mailbox ||= current_user.mailbox
end
In my view I have:
<%= render mailbox.inbox %>
Which renders each conversation subject under a bullet list with a link to trash the conversation. How do I style this or modify how it renders? I can't seem to find the code anywhere that let's me modify how this renders.
mailbox.inbox is just an array of conversation objects. The magic here comes from the way that Rails automatically renders a partial for each object in a collection when an array is passed to render. You can modify how the collection is rendered by creating your own partial that does whatever you want to do with that array of conversations. This describes it further:
https://github.com/RKushnir/mailboxer-app/issues/2
And this part of the Rails guide describes this behavior (might help when you are figuring out how to customize - see section 3.4.5):
http://guides.rubyonrails.org/layouts_and_rendering.html#using-render
Related
I have 4 links on the page (dresses, skirts, shirts, hats) and I want them to be always different depending on the the page. Let's say we click on hats and the links there would be shirts, dresses, skirts, so the current category we are on won't be displayed.
I found something similar here [1]: Render different show pages with category in ruby on rails
But this is not really what I want, as I need to render few links (not one).
My thinking is to create 4 different partials and render 3 links if the params = to the one we don't want to display. Is that a good thinking, or is there any better way of doing it?
You did not provide the exact code, so based on what I assume you will approximately have, you could do something like this:
# Somewhere in your controller
def index # or any action really
...
#current_category = Category.find(params[:category_name]) " # (Or however you want to refer to your category object.
#all_categories = Category.all # (Or an array of plain strings, which would then better be set in some before_action hook so it is present in each of your different pages.)
...
end
# In your view
(#all_categories - #current_category).each do |category|
<%= render "categories/link_card", category: category %>
end
And then in your partials categories/_link_card.html.erb you can have the code for showing the link to any category, using the input variable category to get the exact details of your category. (E.g. name, url).
So I'm trying to re-create GitHub version control for let's say posts. I've found a way to re-create an original post using duplicate AND another method to create a new post based on the original. Cool.
My issue is being able to display both the original and the new on the same page.
What I've attempted thus far is to just rely on the show method with having:
def show
#post = Post.find(params[:id])
end
Then in the view have in the form a checkbox to allow a user to select multiple posts, click a submit, and a new page renders displaying both side by side. Preferably showing the differences between the two but that's a wish list as I deal with this first.
Actually could I just simply do?:
def other_show
#post = Post.where(params[:id])
end
I also added in status as a boolean to help on the view for marking the checkbox. Would I then need to put something in the other_show method about the status?
If you want to "recreate" some sort of version control I suggest you use something like the audited. Instead of building your own. From your example and comments it seems you don't have a clear relation between all related (versions of) posts.
Using this gem, each change to the Post content (for example, if configured properly) would be stored as an audit.
Showing the differences is a different problem. That's usually called a diff and you can find gems that do it for you, for example: diffy
To show 2 different entities on one page you need to give posts_controller both ids.
Declare your show method like this:
def show
#original = Post.find(params[:id])
#compared = Post.find(params[:compared_id])
end
Correct route to this method will look like this:
/posts/:id?compared_id=:another_id
# Example: /posts/1?compared_id=2
To construct such a link in your view, you need to declare link_to method like this:
<%= link_to '1 <> 2', post_path(#post, compared_id: '2') %>
If you want to have a page where user can check 2 checkboxes for certain posts, you'll need to construct such href via Javascript.
But in fact I wouldn't suggest you to modify show method for such a task. It is better to use show method only for showing one entity from database. You can create another method, e.g. compare and pass both parameters there.
def compare
#original = Post.find(params[:original_id])
#compared = Post.find(params[:compared_id])
end
In routes.rb
resources :posts do
get 'compare', on: :collection
end
It will give you helper compare_posts_path, which will lead to /posts/compare and you'll need to pass original_id and compared_id to it, like this:
<%= link_to 'Compare', compare_posts_path(original_id: 'some_id', compared_id: 'some_another_id') %>
It will result to
/posts/compare?original_id=some_id&compared_id=some_another_id
I've got a table full of information at the moment, Ideally i need the information from a database table to be viewed via a link.
I only have the controller and some standard html (the html is just a h1 tag at the moment)
The HTML will be standard throughout like a template.
The way i'm seeing what i want in my head is the users will get a link which would be events_prev/{{id from DB here}} and depending on the ID the information on the page will be populated from the corrisponsing DB Row
Heres my controller
class Events::EventsPrevController < ApplicationController
def index
#events = Event.where(id: id)
end
def show
render :nothing => true
end
end
Sorry if its super confusing.
Welcome to rails.
Ok, there's a couple of things that will get you in the right directions. Firstly, you REALLY need to do a little reading to understand how the controller and the routes and the views are linked together in rails, that'll help you tons.
But moving on to your specific issues:
Parameters:
All data passed via a url (get, post, put, doesn't matter the method) is available in the controller in an array object called params - So that means when want to access the data the user submitted, you'll use something like
#event = Event.where(id: params[:id])
Routes:
It looks like you're trying to use the index page. In rails index is a RESTful route which generally points to a collection of model objects. The show route will point to an individual object so you should instead make your link point to the show path instead of the index path.
You can view the routes available on a model on a command line using:
bundle exec rake routes
An example of what your routes might look like:
prev_events GET /prev_events(.:format) prev_events#index
POST /prev_events(.:format) prev_events#create
new_prev_event GET /prev_events/new(.:format) prev_events#new
edit_prev_event GET /prev_events/:id/edit(.:format) prev_events#edit
prev_event GET /prev_events/:id(.:format) prev_events#show
PATCH /prev_events/:id(.:format) prev_events#update
PUT /prev_events/:id(.:format) prev_events#update
DELETE /prev_events/:id(.:format) prev_events#destroy
Link
Based on the routing table, you now should see that the link you need your users to click on might look like this (given that event is your object:
<%= link_to event.title, event_path(event.id) %>
or shortcutted
<%= link_to event.title, event %>
View
For the view this is entirely dependent on the data in the Event model. Since the data is stored in #event you'll simple use the attributes on the event model to render the html however use like, e.g.
<h3><%= #event.title %></h3>
<span><%= #event.start_time %></span>
You should read up on Rails controllers: by default the action index is used to show all of the records and what you're talking about should belong to the show action. The default routes take care of the id passing to your show action.
Index action is mean to show list of items in view and Show action is used to show a single item.
what you are doing in index is actually mean to be in show action.
Reason:
#events = Event.where(id: id)
this line will give u a single record in every case it means it should be in Show action.
your code should look like:
def show
#event = Event.find(params[:id])
[your logic: what you want to do with that #event]
end
I have a method in my posts_controller to display most viewed posts.
def top
#posts = Post.all.order("post.views DESC").page(params[:page]).per(10)
end
In routes I have
resources :posts do
collection do
get :top
end
end
The problem is: when i go to /posts/top i have an error: Missing template posts/top, application/top Do I need to write view files for my every method (top isn't the only one) or I can somehow display them in my index file without duplication of code?
Just render the index template at the end of your method:
def top
#posts = Post.all.order("post.views DESC").page(params[:page]).per(10)
render :index
end
I would suggest you to have a close look to rails layouts and rendering documentation. You will get your answer as well concept behind them. Below is the snippet of doc.
In most cases, the ActionController::Base#render method does the heavy lifting of rendering your application's content for use by a browser. There are a variety of ways to customize the behavior of render. You can render the default view for a Rails template, or a specific template, or a file, or inline code, or nothing at all. You can render text, JSON, or XML. You can specify the content type or HTTP status of the rendered response as well.
So I've got pagination with Kaminiari set up on my app, which is a forum. When someone replies to the thread, I want to direct them to the last page of the thread. It seems like it'd be easy enough to hard code the logic to get the last page based on what I'm using for record numbers, but is there a built in method to get the last page?
In my current version of kaminari (v0.12.4) the following works:
users = User.page(params[:page])
last_page = users.num_pages
num_pages is defined in https://github.com/amatsuda/kaminari/blob/master/lib/kaminari/models/page_scope_methods.rb.
If you want to add a last_page method, I suggest the following:
module Kaminari
module PageScopeMethods
def last_page
num_pages
end
end
end
It seems that this thread has an answer.
You can write a method to achieve this if not already present in Kaminari . This should be present since Kaminari also renders the page numbers for navigation.
Say, #records is list of db records where you performed #records.page(1) to show the get the current set of records,
The last page number is defined by (#records.total_count / per_page.to_f).ceil .
For other people's sake, I'll share what worked for me.
Associations
Conversation has_many Messages
Message belongs_to Conversation
In Conversation show page, I want to paginate every 10 messages
messages = conversation.messages.page(params[:page]).per(10)
last_page = messages.total_pages
Then I want to create a link to this show page which will show me the last page. I just made a helper method
def create_link_to_last_page(conversation)
content_tag :div do
link_to("Show", url_for(controller: 'conversations', action: 'show', id: conversation.id, page: last_page))
end
end