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.
Related
I have an app where Question model has_many relationship with Option. I also have a button to add options while creating a question. Every question has only one correct answer. So when I create a question and click on Add Option button, new option is created but the new radio button associated with it has different name. In fact the name of radio button is of the form question[options_attributes][i][is_answer] where i is id. As far as I know radio buttons should have the same name to work as a collection or group. So how can I make it work as a group even if I create any number of options for a single question?
html.erb
<%= form_for #question do |form| %>
<div class="field">
<%= form.label :body %>
<%= form.text_area :body %>
</div>
<%= form.fields_for :options, question.options.each do |a| %>
<div class="field">
<%= a.label :options %>
<%= a.text_area :body %>
<%= a.radio_button :is_answer, "options" %>
<%= a.check_box :_destroy %>
<%= a.label :_destroy, 'delete' %>
</div>
<% end %>
<%= form.submit 'Add option', :name => "add_option" %>
<%= form.submit 'Delete options', :name => "remove_option" %>
<div class="actions">
<%= form.submit %>
</div>
<% end %>
controller.rb
class QuestionsController < ApplicationController
def new
#question = Question.new
#question.options.build
end
def create
#question = Question.new(question_params)
#question.user = current_user
if params[:add_option]
#question.options.build
else
respond_to do |format|
if #question.save
format.html { redirect_to #question, notice: 'Question was successfully created.' and return }
format.json { render :show, status: :created, location: #question }
else
format.html { render :new }
format.json { render json: #question.errors, status: :unprocessable_entity }
end
end
end
render :action => 'new'
end
private
# Use callbacks to share common setup or constraints between actions.
def set_question
#question = Question.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def question_params
params.require(:question).permit(:body, options_attributes: [:id, :body, :question_id, :created_at, :updated_at, :is_answer])
end
end
There are two options:
Using JavaScript on the client-side to uncheck the radio buttons.
Using radio buttons with the same name. It this case you will have to change the way you pass the :is_answer parameter and manually assign the value in options_attributes.
Method 1 details:
See this question radio different names - only check one
Method 2 details:
Instead of passing :is_answer parameter for each option you can pass a single parameter for the question having chosen answer id as the value. Lets name it "answer_id". We want this parameter to be in the params[question]
hash in the controller, so the whole name will be "question[answer_id]". Although radio buttons are generated for each option, only the chosen one will be sent to the server as they all have the same name.
<%= form.fields_for :options, question.options.each do |a| %>
<div class="field">
<%= a.label :options %>
<%= a.text_area :body %>
<%= radio_button_tag "question[answer_id]", a.object.id, a.object.is_answer? %>
<%= a.check_box :_destroy %>
<%= a.label :_destroy, 'delete' %>
</div>
<% end %>
https://apidock.com/rails/v4.2.7/ActionView/Helpers/FormTagHelper/radio_button_tag
In the controller you will have to manually assign the option's is_answer parameter based on the answer_id value.
def question_params
result = params.require(:question).permit(:body, :answer_id, options_attributes: [:id, :body, :question_id])
answer_id = result.delete(:answer_id)
result[:options_attributes].values.each do |option_attrs|
option_attrs[:is_answer] = option_attrs[:question_id] == answer_id
end
result
end
If you need further details please let me know. I will update the answer to give more information.
I created a "select_tag" field and I need it when the user clicks save all the values of this field to be passed by params to the controller. The problem is that when I click save, only the first value entered in this field is passed to the controller.
To better understand, the "select_tag" field is populated through another field, the "f.text_field :members" field. When I click on an "add" button the value of the "f.text_field :members" field is passed to the "select_tag" field and so I want to be able to check all these values from the "select_tag" field to validate and save, how do I do that? As I already said, only the first value entered is passed.
Looking at the params now, I realized that the value that returns as "params" is just the value that is selected in the dropdown, the other values are not considered. How do I pass all values in the dropdown?
Code:
<%= form_for(#focus_group) do |f| %>
<% if #focus_group.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#focus_group.errors.count, "error") %> prohibited this focus_group from being saved:</h2>
<ul>
<% #focus_group.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<script type="text/javascript">
$(function() {
$('#focus_group_moderator, #focus_group_members').autocomplete({
source: '/focus_groups/autocomplete.json'
});
});
function add(){
var value = $('#focus_group_members').val();
var select = document.getElementById("membersAdded");
var option = document.createElement("option");
option.text = value;
option.value = value;
select.add(option);
$('#focus_group_members').val("");
}
function removeFromSelect(){
var select = document.getElementById("membersAdded");
select.remove(select.selectedIndex);
}
</script>
<div class="field">
<%= f.label :name %><br>
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :topic %><br>
<%= f.text_field :topic %>
</div>
<div class="field">
<%= f.label :moderator %><br>
<%= f.text_field :moderator %>
</div>
<div class="field">
<%= f.label :description %><br>
<%= f.text_area :description %>
</div>
<div class="field">
<%= f.label :members %><br>
<%= f.text_field :members %>
<input onclick="add()" type="button" value="Add" /><br>
<%= select_tag(:membersAdded, options_for_select([])) %>
<input onclick="removeFromSelect()" type="button" value="Remove" /><br>
<br>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
CONTROLLER
class FocusGroupsController < ApplicationController
before_action :set_focus_group, only: [:show, :edit, :update, :destroy]
include FocusGroupsHelper
def index
if(params[:term])
#profile = Profile.all.select("name", "id")
#lista = Array.new
#profile.each do |x|
#lista.push(x.name)
end
respond_to do |format|
format.html
format.json { render json: #lista.to_json}
end
else
#focus_groups = FocusGroup.all
end
end
def show
end
def new
#focus_group = FocusGroup.new
#membersAdded
respond_to do |format|
format.html
format.json { render json: Profile.all.to_json}
end
end
def edit
end
def create
#moderator= find_profiles_id(focus_group_params[:moderator])
#moderator.each do |f|
#moderator_id = f.id
end
#params = focus_group_params
#params[:moderator] = #moderator_id
#focus_group = FocusGroup.new(#params)
if #focus_group.save
redirect_to #focus_group, notice: 'Focus group was successfully created.'
else
render :new
end
end
def update
if #focus_group.update(focus_group_params)
redirect_to #focus_group, notice: 'Focus group was successfully updated.'
else
render :edit
end
end
def destroy
#focus_group.destroy
redirect_to focus_groups_url, notice: 'Focus group was successfully destroyed.'
end
def autocomplete
if(params[:term])
#profile = Profile.all.where("user_id <> 0 and is_template = 'f' and name LIKE ?", "#{params[:term]}%").select("name", "id")
#lista = Array.new
#profile.each do |x|
#lista.push(x.name)
end
respond_to do |format|
format.html
format.json { render json: #lista.to_json}
end
end
end
def find_profiles_id(name)
return Profile.all.where("name LIKE ?", "#{name}%").select("id")
end
def find_profiles_name(id)
#profile = Profile.all.where("id = ?", "#{id}").select("name")
#profile.each do |e|
#name = e.name
end
return #name
end
private
def set_focus_group
#focus_group = FocusGroup.find(params[:id])
end
def focus_group_params
params.require(:focus_group).permit(:name, :topic, :moderator, :description, :members, :membersAdded)
end
end
Several ways to approach this -- but the select box itself doesn't make any sense to use in this situation. Provides no utility. Here's one way. Do you have a separate members model? It seems like you're essentially trying to do a nested form. If you don't have a members model, create one. Create a focus group separately and put the form for members on the FocusGroup's show page. A focus group has many members and member belongs to a focus group (has a focus group id). This will allow you to say #focus_group.members and get all the members back.
If you must add them on the same form for some reason (I don't think this is optimal), you'll want to do so via a nested form with a form builder that allows you to add many at once. You could also make a service object but that is more complicated.
Another option, which I like less, would be to push all of the members to an array and then pass it as a param on submit. Instead of adding the members to the select box you'd just push them to an array. Then you would set the final array value to members_added (or whatever you name the parameter). You'll need to unpack that array in the controller to create each member. I like this much less. The first option is the cleanest. I think this is the third best approach of the three.
I'm working with Ruby on Rails, trying to get my search bar to display the results. I've tried searching for similar issues, but most already had search working and weren't getting it to work right.
in my html I have:
<%= form_tag users_path, :method => 'get' do %>
<p>
<%= text_field_tag :search, params[:search] %>
<%= submit_tag "Search", :name => nil %>
</p>
<% end %>
<div class="scrollBox">
<%= will_paginate%>
<ul>
<% #users.each do |user| %>
<li>
<%= link_to user.name, user, {:class=>"signout-style"} %>
</li>
<% end %>
</ul>
<%= will_paginate %>
</div>
In my users controller I have:
def index
#users = User.paginate(page: params[:page])
#searches = User.search(params[:search])
end
In my users model I have:
def self.search(search)
if search
find(:all, :conditions => ['name LIKE ?', "%#{search}%"])
else
find(:all)
end
end
I was using the railscast episode #37
Any help is appreciated!
Update the index action as below:
def index
#users = User.search(params[:search]).paginate(page: params[:page])
end
Currently, you are storing the search results in instance variable #searches with this line:
#searches = User.search(params[:search])
BUT in your view you are accessing #users which is set as #users = User.paginate(page: params[:page]). So, you always see all the users in the view and not the searched users.
UPDATE
As you are using Rails 4.0.2, I would suggest you to refactor your search method as below:
def self.search(search)
if search
where('name LIKE ?', "%#{search}%")
else
all
end
end
inside one of my view pages I'm using old fashion way of presenting data but I have problem in converting a string like "User.country.name" to a query statement.
I'm using a loop like below :
#columns = ['id','email','name','country.name']
table = User.all
<% table.each do |row| %>
<% #columns.each do |field| %>
<%= row[field] %>
<% end %>
<% end %>
The table shows almost all data except for column "country.name". I can't use constantize for country.name it gives me error. Any solution ? Thanks
Your User doesn't have an attribute country.name, it has an association country and that association has an attribute name.
You could set up a delegate:
class User < ActiveRecord::Base
delegate :name, to: :country, prefix: true
# ...
end
This creates a method User#country_name, returning country.name.
Now you can adapt your loop, using public_send to call the methods: (I've changed the variable names to make it clearer)
#methods = [:id, :email, :name, :country_name]
records = User.all
<% records.each do |record| %>
<% #methods.each do |method| %>
<%= record.public_send(method) %>
<% end %>
<% end %>
#users = User.select(:id, :email).joins(:countries)
<% #users.each do |user| %>
<%= user.id %>
<%= user.email %>
<%= user.countries %>
<% end %>
http://api.rubyonrails.org/classes/ActiveRecord/QueryMethods.html#method-i-joins
Wish it helps
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