I'm doing archives for my blog ,actually I'm moving from rails to sinatra because of the requirements.I'm trying the same for Sinatra
In my app.rb:
def index
#posts = Post.all(:select => "title, id, created_at", :order => "created_at DESC")
#post_months = #posts.group_by { |t| t.created_at.beginning_of_month }
end
and in Layout.erb :
<div class="archives">
<h2>Blog Archive</h2>
<% #post_months.sort.reverse.each do |month, posts| %>
<h3><%=h month.strftime("%B %Y") %></h3>
<ul>
<% for post in posts %>
<li><%=h link_to post.title, post_path(post) %></li>
<% end %>
</ul>
<% end %>
Can anyone please help me how to do it for sinatra? I'm trying the same code and I'm getting this :undefined method `sort' for nil:NilClass
You are not using Sinatra's notation for defining actions. Instead of:
def index
# your code...
end
You need to define actions like so:
get '/' do
# your code...
end
You should probably read this before continuing: http://www.sinatrarb.com/intro.html
Related
I'm using the acts_as_votable gem to like and unlike "Deals" in my Ruby on Rails project. My user is set to act_as_voter and my deal is set to acts_as_votable, but for some reason everything is set to like as soon as a new user is created, and they can't unlike the deal. For some reason my list of deals all have an unlike button and it doesn't actually do anything but refresh the page. Here's some of my code.
app/views/catalog/index.html.erb
<ul class="deals_list">
<% #deals.each do |deal| %>
<li>
<div>
...
<div class="favorite">
<% if account_signed_in? and current_account.accountable_type == "Personnel" %>
<%= image_tag("dark-favorite.png") %>
<% if deal.liked_by current_account %>
<%= link_to unlike_deal_path(deal), method: :put do %>
Unlike
<% end %>
<% else %>
<%= link_to like_deal_path(deal), method: :put do %>
Like
<% end %>
<% end %>
<% end %>
</div>
</li>
<% end %>
</ul>
app/controllers/deals_controller.rb
def like
#deal = Deal.find(params[:id])
#deal.liked_by current_account
redirect_back(fallback_location: catalog_index_url)
end
def unlike
#deal = Deal.find(params[:id])
#deal.unliked_by current_account
redirect_back(fallback_location: catalog_index_url)
end
config/routes.rb
resources :deals do
member do
put 'like', to: "deals#like"
put 'unlike', to: "deals#unlike"
end
end
Be sure and read the entire Readme because you're using the library wrong.
To check if a voter has voted on a model, you can use voted_for?. You can check how the voter voted by using voted_as_when_voted_for.
I zeroed in on your problem because I was expecting to see a "?" after the deal.liked_by call, which would indicate a boolean result (by convention, not always the case).
So use this instead:
<% if current_account.voted_for? deal %>
I'm discovering the gem will_paginate which is great ! But I'm facing a problem of using. I'm building a group>post>comments app, so in my group show page i'm displaying posts and their comments. To limit the numbers of queries, i'm using includes method like this :
Group_controller :
def show
#posts = #group.posts.order(upd_at: :desc).includes(:user).includes(comments: :user).paginate(page: params[:page], per_page: 10)
end
So I would like to also paginate my comments. Do you know a way to do that ?
My code :
Group_show =
<h1>Groupe <%= #group.name %></h1>
<div class="post_list<%=#group.id%>">
<%= render #posts %>
</div>
<%= will_paginate #posts, renderer: BootstrapPagination::Rails %>
And my posts/_post =
<% #comments = post.comments %>
<ul id="comment_list<%=post.id%>">
<%- if #comments.any? %>
<%= render #comments, post: post %>
<%= will_paginate #comments, renderer: BootstrapPagination::Rails %>
<% end %>
</ul>
By the way if you have a method to define #comments directly in the Groups_controller(show), it can be really useful ;)
Not 100% tested, but I think this should work. Do you know how all these components work? If not, let me know and I can explain.
posts/_post
<% #comments = post.comments.order(created_at: :desc).limit(3) %>
<ul id="comment_list<%=post.id%>">
<%- if #comments.any? %>
<%= render #comments, post: post %>
<%- if post.comments.offset(3).exists? # this is more efficient than count > 3 bc it quits counting after 3 %>
<!-- the below link_to creates: href="/posts/:id/comments" ... -->
<!-- ... and `remote: true` makes that an ajax request -->
<li><%= link_to "more", comments_post_path(post), class: "more-comments-btn", remote: true %></li>
<% end %>
<% end %>
</ul>
config/routes.rb
resources :posts do
# `member do` is explained here: http://guides.rubyonrails.org/routing.html#adding-more-restful-actions
member do
get :comments
end
end
posts_controller.rb
# GET /posts/:id/comments
def comments
#post = Post.find(params[:id])
#comments = #post.comments.order(created_at: :desc)
# since you requested this url via ajax with `remote: true` rails will automatically render `posts/comments.js.erb` ...
# ... rather than a typical html request where rails would automatically render `posts/comments.html.erb`
end
views/posts/comments.js.erb
// some people like to use render #comments as shorthand like you did above. I'm a fan of being more explicit like the below
$("#comment_list<%= #post.id %>").html("<%= escape_javascript(render partial: 'comments/comments', locals: {comments: #comments, post: #post}) %>");
// now remove the more comments button
$("#comment_list<%= #post.id %>").find(".more-comments-btn").remove();
The documentation here explains the use of remote: true for ajax requests. Scroll down to section "3.1.2 link_to" and then section 5.1 for the controller and js.erb view.
I'm building a micropost rails app where users can create posts, I created a route and an action to display posts that belong to the signed-in user, happens that the general index layout for posts is exactly the same as the "myposts" layout so instead of duplicating code I would like to use just one layout with different parameters.
This is what I have until now:
routes.rb
resources :posts
get '/myposts', to: 'posts#my_posts', as: 'myposts'
posts_controller.rb
def index
#posts = Post.all
end
def my_posts
#myposts= Post.where(user_id: current_user.id)
end
index.html.erb
<% #posts.each do |post| %>
<div>
<h1><%= link_to post.title, post %></h1>
<%= link_to image_tag(post.meme_url(:thumb)), post, :target => "_blank" %>
</div>
<% end %>
my_posts.html.erb
<% #myposts.each do |post| %>
<div>
<h1><%= link_to post.title, post %></h1>
<%= link_to image_tag(post.meme_url(:thumb)), post, :target => "_blank" %>
</div>
<% end %>
Thanks in advance!
You can use 'render' on 'my_posts' action - http://guides.rubyonrails.org/layouts_and_rendering.html#using-render
Add before 'end' in my_posts action:
render :index
I have the following action method:
class CommandsController < ApplicationController
.
.
.
def usersList
#command = Command.find_by(id: params[:id])
#users_list = #command.user_commands.paginate(page: params[:page], per_page: 10)
end
end
The following view: users_list.html.erb
<% provide(:title, "Command list") %>
<h1>Lista Utenti per <%= #command.content %></h1>
<%= will_paginate #users_list %>
<ul class="users">
<% #users_list.each do |user| %>
<li><%= user.name.capitalize %>, <%= user.email %></li>
<% end %>
</ul>
And in the routes.rb
get 'commands/:id/usersList' => 'commands#users_list', as: :list
Now I don't understand why going to lochalhost:3000/commands/1/usersList I receive the following error:
undefined method `content' for nil:NilClass
refered to line <h1>Lista Utenti per <%= #command.content %></h1>
Why does it do so? When I call an action, before it renders the page and then after it executes the code inside the method?
I resolved the problem by changing the names: usersList --> userslist and then users_list.html.erb --->userslist.html.erb and in the routes.rb ----> get 'commands/:id/userslist' => 'commands#userslist', as: :list
Then I don't understand the naming convention...if I declare an action usersList how should I rename the related view?
You should change your action name to users_list.
I'm a Rails noob and I'm following a blog post I found here...
I have everything working up until the end. Then things get nebulous.
So if I have this in my helper...
module ApplicationHelper
def display_content_with_links(tweet)
tweet.content.gsub(/(http:\/\/[a-zA-Z0-9\/\.\+\-_:?&=]+)/) {|a| "#{a}"}
end
end
Shouldn't I be able to have my tweets display in my view with this...
What am I doing wrong?
You are going to need a controller and view to have this display. Something simple like:
# app/controller/tweets_controller.rb
TweetsController < ApplicationController
def index
#tweets = Tweet.get_latest
end
end
and in the view:
# app/views/tweets/index.html.haml
%ul
- #tweets.each do |tweet|
%li
= display_content_with_links tweet
or if you use erb
# app/views/tweets/index.html.erb
<ul>
<% #tweets.each do |tweet| %>
<li>
<%= display_content_with_links tweet %>
</li>
<% end %>
</ul>
This is a pretty basic example that might not even come close to what you want, but it should point you in the right direction.
Actually, you should add
#tweet = Tweet.all
To the controller#action you have setup already, then iterate over them in your view:
<ul>
<% #tweets.each do |tweet| %>
<li><%= display_content_with_links tweet %></li>
<% end %>
</ul>