if else condition using three models rails - html

I have 3 models
Users: id , name
Jobs: id, user_id, title
Applications: id, job_id, user_id
In Job#show page I am trying to put a button which is visible only to people who haven't applied to the job, haven't created the job and are logged in . I am using devise. I have managed to build correct relationship in these models (thanks to SO) as following.
user.jobs #list all jobs posted by the user
jobs.applicants #list all applicants on the job
Question is how to formulate if else condtion which shows button which submits a form (hidden) to the job#show page and puts job_id and user_id in the application model.
I tried
<% if user_signed_in? %>
<% if job.user_id = current_user.id %>
<div style="text-align:center;" class="widget">
<%= link_to(new_user_session_path, :class => "g-btn type_primary") do %>
<i class="icon-external-link"></i> Apply for the job
<% end %>
</div>
<% end %>
<% end %>
I can't seems to get the idea on how to get around error of object.id nil.

You seem to have missed an = sign.
You can improve your if condition like this
<% if user_signed_in? && job.present? && job.user_id == current_user.id %>
your logic here
<% end %>

how does a user apply for the job? using what controller?
you code has the user logging in again,
does the user need to create an application object and does it require additional information from the user to complete the process, or is more along the lines of send existing information from the user to information stored in the job.
If the latter you can do something like this.
resources :jobs do
member do
post 'apply'
end
end
<% if user_signed_in? %>
<% unless job.user == current_user %>
<div style="text-align:center;" class="widget">
<%= link_to 'Apply', apply_job_path(job), method: :post %>
</div>
<% end %>
<% else %>
<%= link_to 'Sign in to apply', new_user_session_path %>
<% end %>
then in your jobs controller
def apply
if Application.create job_id: params[:job_id], user: current_user
redirect_to jobs_path, notice: "You have applied, good luck!"
else
... do something for failure...
end
end

Try this instead
<% if user_signed_in? %>
<% if job.user_id == current_user.id %>
<div style="text-align:center;" class="widget">
<%= link_to "Apply for the job" new_user_session_path, :class => "g-btn type_primary" %>
</div>
<% end %>
<% end %>
and it might be better to change this line
<div style="text-align:center;" class="widget">
to
<div class="widget center">
and add a class named center to the relevant css sheet

Related

Ruby On Rails - Button run function

Okey, so im kinda new to ruby on rails. Im trying to call a function when im pressing a button. But i have no idea how to do this.
This is basicaly what im trying to do:
<% button_to 'Ban User', call_this_function %>
<% this_function %>
#user = User.find(:id)
#user.deactivated("true")
<% end %>
Here is some actual code that I wrote
<% if has_role?(:admin) %>
<% if !#user.deactivated %>
<% if !#user.has_role?(:admin) %>
<%= link_to 'Ban User', new_discussion_path, class:"button is-danger" %>
<% end %>
<% else %>
<%= link_to 'Unban User', new_discussion_path, class:"button is-success" %>
<% end %>
<% end %>
But this only redirects to a page to where I can create a new discussion. What I'm trying to do is to just call a named function when impressing the button, but do not redirect to some other page. I'm sorry for the lack of code, but please ask if you need some clarification.
add a controller action to your corresponding controller like,
def ban_user
#user = User.find(params[:id])
#user.deactivated("true")
end
add this action to your routes.rb
get 'controller/ban_user'
now you can add the link to your views
<%= link_to 'Ban User', controller_user_ban_path(:id => #user.id), class:"button is-danger", remote: true %>
this will call the function without loading the page.

Rails: Get form to only render when certain conditions are met

Im trying to get this loop to only render the reviews form for services which doesnt already have a review. I can't get it to function properly. Any ideas?
<% #services.each do |service| %>
<% if service == #booked && !#hasReview %>
<%= form_for(service, service.reviews.new) do |f| %>
<label>Create review for</label> <%= label_tag service.title %>
<div id="user_stars"></div>
<div class form-group>
<%= f.text_area :comment, rows: 3, class: "form-control" %>
</div>
<%= f.hidden_field :service_id, value: service.id %>
<div class="actions">
<%= f.submit "Create", class: "btn btn-primary" %>
</div>
<% end %>
<% end %>
<% end %>
The #booked and #hasReview actions are working correctly by themselves. So I guess Im setting it up wrongly with the IF
EDIT:
services_controller.rb
def show
#user = User.find(params[:id])
#services = #user.services
#booked = Booking.where("service_id = ? AND user_id = ?", #service.id, current_user_id).present? if current_user
#reviews = #service.reviews
#hasReview = #reviews.find_by(user_id: current_user_id) if current_user
end
reviews_controller.rb
def create
#review = current_user.reviews.create(review_params)
redirect_to request.referer
end
Your logic looks good, so I'm guessing your problem is with this part of your if statement:
if service == #booked
Judging from this line in your services_controller:
#booked = Booking.where("service_id = ? AND user_id = ?", #service.id, current_user_id).present? if current_user
it looks like the #booked instance variable is a boolean. So you're comparing a boolean to service, but it doesn't look like service is a boolean.
So you'll want to change the if statement so that you're comparing two equivalent types, and in your case you probably want to compare two boolean values.

Separating posts in a newsfeed using CSS/BootStrap

I'm currently trying to render a newsfeed, similar to that of FB on a Rails application I'm working on. Unfortunately, I'm not the greatest when it comes to CSS and I'm having some issues trying to display different posts. This issue occurs whether I'm using BootStrap or plain CSS. I do believe it's something to do with the loop that is created by <% #posts.each do |post| %> Currently, whenever a new post is made, it wraps inside the previous post; thus the more posts that are made, the thicker the border gets.
Image:
<% if #posts.any? %>
<% #posts.each do |post| %>
<div class="well">
<%= post.user.first_name %> <%= post.user.last_name %><br>
<% if !post.image.exists? %>
<h2> <%= post.text %> </h2>
<% else %>
<h2> <%= link_to post.text, post_path(post) %> </h2>
<%= link_to post_path(post) do %>
<p><%= image_tag post.image.url(:medium) %></p>
<% end %>
<% end %>
<% if #user %>
<% if current_user.voted_up_on?(post) %>
<%= link_to "Like", dislike_post_path(post), method: :put %>
<% else %>
<%= link_to "Like", like_post_path(post), method: :put %>
<% end %>
<% end %>
<%= "Likes: #{post.get_upvotes.size}" %>
<% if post.user == current_user %>
<%= link_to "Edit", edit_post_path(post) %>
<%= link_to "Delete", post_path(post), method: :delete %>
<% end %>
<div id='comments_div' class="comments-index">
<%= render post.comments %>
</div>
<% if current_user %>
<%= form_for [post, post.comments.new ], remote: true do |f| %>
<%= f.text_area :text, placeholder: 'Add a comment' %>
<%= f.submit 'Comment' %>
<% end %>
<% else%>
<p>You need to <%= link_to "sign in", new_user_session_path %> to comment</p>
<% end %>
<% end %>
<% else %>
No posts have been added!
<% end %>
</div>
Any help would be greatly appreciated! Thanks.
Edit: OK, please take a look at the new image -- hopefully that will make the issue slightly more obvious. Additionally, I've removed all the dead tags and replaced them with just one: BootStrap's 'well' class. So, there you have it. All the information you need is within the code above.
from your description it sounds as though an html element is not being properly closed. Run the page source through an html validator and that could show you the problem.
If you don't want to take a structured problem solving approach, try adding another </div> to the end of your posts-index container.
Your issue is very simple, just that its not clear due to poor indendation.
A simple way to explain what you did is:
<-- if (start) -->
<-- do (start) -->
<-- post (start) -->
(post is not ending here, hence it breaks the layout)
<-- do (end) -->
<-- if (end) -->
<-- post (end) -->
Mistake in the above should be simple to understand so if you move your last </div>(of the well class) just before the second last <% end %>(of the <% #posts.each do |post| %> loop) it should fix the issue. So the last few lines should be
<% else%>
<p>You need to <%= link_to "sign in", new_user_session_path %> to comment</p>
<% end %>
</div>
<% end %>
<% else %>
No posts have been added!
<% end %>
Sounds to me like it could be a misplaced
<% end %>
or a missing
</div>
that is causing this behavior.
Proper indentation will point to where to close off actions or divs

Rails simple-form with multiple instances of the same object

I am trying to create a rails form using simple form that uses nested resources. However, I want to be able to submit multiple instances of the associated resource. Example below will probably explain it better.
<div class="tab-pane active" id="reminder">
<%= simple_form_for #collection, html: {multipart: true}, url: collection_index_path do |m| %>
<%= render partial: "collection/tabs/reminder", locals: { :m => m } %>
</div>
-inside partial
<% 9.times do |j|%>
<div class="tab-pane" id="<%= j %>">
<%= m.simple_fields_for :reminder do |p| %>
<%= p.input :heading %>
<%= p.input :message %>
<% end %>
</div>
There is a tabbed pane in which the user can click through 9 tabs to set up to 9 reminders, all should be associated with a collection (collection model accepts nested attributes for reminder). However, the way I have it setup now, the controller only gets what was set in the last reminder in the params. Anyway ideas would be appreciated.
There must be some way to distinguish tabs before submitting to controller. And i think answer might be here.
i.e. it looks like this:
<% 9.times do |j|%>
<div class="tab-pane" id="<%= j %>">
<%= m.simple_fields_for :reminders do |p| %>
<%= p.input :heading %>
<%= p.input :message %>
<% end %>
</div>
<% end %>

If i pluck 2 values, how can i read them in html ruby

In my controller i find a uniq notebook and user name.
but i want to be able to check in my html code that it shows only one type of user.
in controller
def index
#allnotebooks = Note.uniq.pluck(:string, :notebook)
#notes = Note.all
end
in my html
<% #allnotebooks.each do |notebook| %>
<% if notebook.string == c_user.name %>
<option><%= notebook %></option>
<% end %>
<% end %>
notebook.string does not work. what am i missing
Also you can do in different way other than using pluck, using select you can do it
like-
In controller code-
def index
#allnotebooks = Note.uniq.select([:string, :notebook])
#notes = Note.all
end
in your html
<% #allnotebooks.each do |notebook| %>
<% if notebook.string == c_user.name %>
<option><%= notebook %></option>
<% end %>
<% end %>
Thanks!!!
Pluck returns an array.
Try notebook.first or notebook[0]
Docs here: http://apidock.com/rails/ActiveRecord/Calculations/pluck
Second example at the bottom applies here.
In your example it should be:
<% #allnotebooks.each do |notebook| %>
<% if notebook[0] == c_user.name %>
<option><%= notebook[1] %></option>
<% end %>
<% end %>
btw you might want to improve this by only loading notebooks where the string equals your user's name.
I am not a good ruby guy, You can write it like
<% #allnotebooks.each_with_index do |notebook, index| %>
<%= notebook[index].string %> => <%= notebook[index].notebook %>
<% end %>
for "a" unique notebook, you do you need to loop it?
just to say:
#allnotebooks.each{|notebook| <%= notebook[0] %> <%= notebook[1] %> }
But there can be better ways.