My app runs on two different database, and I use the application logic to work on them.
I have the User model on an external db and I only records the id on my default_role class.
So in the index template I fetch the accounts from remote, and for each of them I have to query my table to print some immutable information and I want to give the possibility to change role in my table
Index information = remote tables information (name surname ecc) + my table information (role)
Using best_in_place to edit the role_id field of my users.
The problem is my index cycle #operators which comes from outside buy I need to change role which is on my side!
- #operators.each do |ope| #cycle users
%tr
%td
- user = User.find_by_bay_id(ope.account_id)
- df = DefaultRole.find_by_operator_id(user.id)
= best_in_place [:admin, df], :role_id, :type => :select, :collection => [[1, 'admin'], [2, 'coordinator'], [3, 'operator'], [4, 'base']]
and my update in controller:
respond_to :html, :json
def index
#operators = some logic from model where I get all the users
end
def update
#df = DefaultRole.find(params[:id])
#df.update_attributes(params[:default_role])
respond_with [:admin, #df]
end
But it didn't even call my update method in the controller.
It normally checks the collection tag, allows me to change it but it doesn't allow me to submit.
What am I doing wrong?
EDIT
My browser doesn't catch any request.
Best_in_place gem uses JSON calls to update the content . In this case you should have respond_to json statement in your controller , something like this :
def update
#df = DefaultRole.find(params[:id])
respond_to do |format|
if #df.update_attributes(params[:default_role])
format.html { redirect_to root_path, notice: 'Role was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #df.errors, status: :unprocessable_entity }
end
end
I find it strange to include variable specifications in your view , they belong to the controller (- user = User.find_by_bay_id(ope.account_id)
- df = DefaultRole.find_by_operator_id(user.id) .
I finally found the error.
https://github.com/bernat/best_in_place/issues/217
It was a Jquery issue on that version of best_in_place. Running:
bundle update
and restarting the server solve the problem, thanks everyone
Related
I am building a Rails app. And in my app, there are Projects where users can "Follow". When a user follows one of the pages, he/she will get updates if somebody uploads/creates a folder/file.
Below is the screenshot when somebody just created a new folder:
And below is the code for "Create" action in my Folder controller:
def create
#folder = current_user.folders.where(project_id: params[:project_id]).create(folder_params)
respond_to do |format|
if #folder.save
#folder.create_activity :create, owner: current_user, :params => {
:project_id => proc {|controller, project| #folder.project.id},
:project_name => proc {|controller, project| #folder.project.name},
}
format.html { redirect_to #folder.project, notice: 'Folder was successfully created.' }
format.json { render :show, status: :ok, location: #folder }
else
format.html { render :new }
format.json { render json: #folder.errors, status: :unprocessable_entity }
end
end
end
As you can see :project_id and :project_name are the parameters for the public_activity when a new folder being created.
And below is the screenshot on how this parameters value looks like in the database after they were saved:
QUESTION:
So my question is, how do i use this parameters values in my activities_controller?
Here is the code for my activities controller right now:
class ActivitiesController < ApplicationController
def index
#activities = PublicActivity::Activity.order("created_at desc").where(owner_id: current_user.following_users, owner_type: "User")
end
end
Instead of using "owner_id:", I want to use the "project_id" value from parameters column. So how can i do this?
Thank you very much in advanced! :)
The parameters field contains a simple yaml dump, so not really easy to search efficiently.
A simple solution would be to use LIKE operator, for instance
PublicActivity::Activity.where("parameters LIKE '%project_id: #{#project.id}%'")
You might want to consider to add custom fields instead.
Thanks for the answer, but I got a better solution than using the parameters value or custom field.
Here is how my activities_controller looks like right now:
class ActivitiesController < ApplicationController
def index
activity_table = PublicActivity::Activity.arel_table
# We want to view all activity of folders related to projects we are follwing
folder_ids = Folder.where(project_id: current_user.following_projects.pluck(:id)).pluck(:id)
# Generate query for all activity related to folders we care about
folders_query = activity_table[:trackable_type].eq('Folder').and(
activity_table[:trackable_id].in(folder_ids)
)
# Generate query for all users that we follow
users_query = activity_table[:owner_id].in(current_user.following_users.pluck(:id))
activity_query = folders_query.or(users_query)
#activities = PublicActivity::Activity.where(activity_query)
end
end
By using this way, I could easily combine the activities from the "Users" and also from the "Projects" that the user follows.
You can modify it to add any other activities such as from the "Comments" or "Voting".
Hope this will help other people out there that are using public_activity gem! :)
I'm having a bit of trouble and I'm not sure if it's even possible to do what I want.
I have a user model with a field called points. I also have a matches model.
I've been trying to use my matches_controller to update the points field of every user when a match gets updated (by a site admin). The goal is to add points if the user selected the correct score.
I'm not sure if I'm able to do this. I'm wondering am I incorrect trying to access the user model from the matches_controller? Because I want to update all fields when a match score is updated, I need to do it from the matches_controller
I've been going around in circles trying to solve this. Am I approaching it incorrectly?
Thanks for reading and hopefully helping.
Here's the relevant code
matches_controller.rb
def update
respond_to do |format|
if #match.update(match_params)
format.html { redirect_to #match, notice: 'Match was successfully updated.' }
format.json { render :show, status: :ok, location: #match }
else
format.html { render :edit }
format.json { render json: #match.errors, status: :unprocessable_entity }
end
end
MatchPick.where(:matchID => params[:id]).update_all(result: match_params[:result], closed: match_params[:played], points: 0)
MatchPick.where(:matchID => params[:id], :userPick => match_params[:result]).update_all(points: 3)
update_user_points
end
def update_user_points
#users = User.all
#users.each do |user|
user.points = 4
puts params
end
end
You can't use update_all unless you're updating a field in all the records to the same value, which is not the case here.
How about this?
MatchPick.where(:matchID => params[:id], :userPick => match_params[:result]).each do |mp|
mp.user.update_attribute(:points, mp.user.points + 4)
end
(this is assuming that MatchPick is a join record between Match and User and has a belongs_to relationship with User)
When I am creating a skid, I am trying to get a value that user has entered so that I can create that record that many times.
in _form.html.erb is where all my code sits. and in the new.html.erb is where I call the form with:
<%= render 'form' %>
Here is the piece of code from form that I am trying to access:
<%= f.label :skid_count %>
<%= f.number_field :skid_count, :value => '1', :required => 'required', :pattern => ValidationValues.c_integer, :placeholder => ValidationValues.p_integer %>
In the controller I am trying to do this:
def create
#skid = Skid.new(params[:skid])
count = params[:skid_count].to_i
# Create record in the database, and return an appropriate message
respond_to do |format|
if #skid.save
for i in 1..count
Skid.new(params[:skid]).save
end
format.html { redirect_to #skid, notice: 'Skid was successfully created.' }
format.json { render json: #skid, status: :created, location: #skid }
else
format.html { render action: "new" }
format.json { render json: #skid.errors, status: :unprocessable_entity }
end
end
end
for some reason the count variable is not picking up the number, if I hard code it and put 3 in there, it would create the record 4 times just as intended, however if I try to get the numeric value based on what user entered, as shown above, it doesn't works. It creates just 1 record every time.
Is there a reason why I cannot access that param?
It's look like you are setting the variable before the record saves, so there is no record to set the variable with at that point. If you move the line down a few spaces, it should work.
def create
#skid = Skid.new(params[:skid])
# Create record in the database, and return an appropriate message
respond_to do |format|
if #skid.save
count = params[:skid_count].to_i # if the record saves, create variable with the new params
for i in 1..count # do your magic
Skid.new(params[:skid]).save
end
I have solved this question by getting the value from the attribute in this manner:
count = params[:skid]["skid_count"]
I hope this helps somebody else stumbled with the same problem.
I will expand on your answer to explain why.
As you are building the field via the form_for helper, it automatically scopes it under the model attributes in the param hash.
params[:skid][:skid_count] would work as well
if you want :skid_count to be outside of the params hash (as to not to trigger forbidden attributes in newer versions of rails, you can build it by just using number_field_tag(:skid_count) which would them be available to your controller as params[:skid_count]
I've got an problem with my update action for a nested resource.
In my app, my orders have many invoices.
Creating a new invoice, I correctly end up with the following url:
/orders/11/invoices/new
And when I edit the invoice, again, it's all correct:
/orders/11/invoices/3/edit
This works fine when the save is a success, however if the validation fails, it routes back to:
/invoices/3
I have the following in my invoices controller:
def update
# #order = Order.find(params[:order_id])
# #invoice = #order.invoices.find(params[:id])
#invoice = Invoice.find(params[:id])
respond_to do |format|
if #invoice.update_attributes(params[:invoice])
format.html { redirect_to(order_invoice_path(#invoice.order, #invoice), :notice => 'Invoice was successfully updated.') }
format.xml { head :ok }
else
format.html { render :action => "edit" }
format.xml { render :xml => #invoice.errors, :status => :unprocessable_entity }
end
end
end
def edit
#invoice = Invoice.find(params[:id])
3.times { #invoice.invoice_items.build }
end
I'm assuming I need to edit the #invoice.errors part but I don't know what to change it to?
Any help appreciated. Jx
When updating failed, you use "render" (comparing with the "redirect_to" in the succeeding path), this brings you to invoice editing path by default. You can use "redirect_to" here to keep the URI path you want, but need remembering to preserve the models' states so your users don't need to fill the entire form all over again.
A detail instruction can be found here: How to make a render :edit call show the /edit in the address bar
Yan
in your form you should add your order, like this:
<%= form_for [#order, #invoice] ... do |f| %>
...
<% end %>
And then uncomment this two lines
# #order = Order.find(params[:order_id])
# #invoice = #order.invoices.find(params[:id])
so your form will send its request to POST /orders/XX/invoices/XX
I have just begun Rails 3. I have generated the below code using the scaffold from Rails 3 on a table called "Logs".
The 'index' function below provides only the records associated with the current_user.id (from the session stored in the session table). The users records are only presented with the following route logged in as user = 3 (see index code below)
localhost:3000/logs
Problem: As a user, I can view a record which is not my record (being user=3) by editing the url manually to show any other record:
localhost:3000/logs/5 'this was entered by user.id=2'
Seeking Solution: How do I prevent manually hacking of the url to prevent a user viewing other user records?
class LogsController < ApplicationController
before_filter :login_required
def index
#logs = Log.where(:user_id => current_user)
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #logs }
end
Please ignore that the new function is missing from the create function below. The code below is to merely demonstrate how I put the user_id into the "Logs" table
def create
#log = Log.new(params[:log])
#log.user_id = current_user.id
respond_to do |format|
if #log.save
format.html { redirect_to(#log)}
format.xml { render :xml => #log, :status => :created, :location => #log }
else
format.html { render :action => "new" }
format.xml { render :xml => #log.errors, :status => :unprocessable_entity }
end
end
The simplest solution would be to check in the show method if the Log to display really belongs to the logged in user:
def show
#log = Log.find(params[:id])
unless #log.user_id == current_user.id
flash[:error] = "unauthorized"
redirect_to :index
end
end
But you will soon have some more things you want to restrict access to, so you should look for an authentication plugin which allows to define the access rights in a declarative manner. Maybe this one: https://github.com/be9/acl9