I have Exercise and User model. User can share his exercises with each other through SharedExercise model. Exercise may be public or private, and users are allowed to add public exercises to their private exercises. I need to add simple link/button to do this, but have no idea how.
Im looking for something like:
def add
#exercise = Exercise.find(params[:id])
current_user.exercises << #exercise
end
but how to pass that to link/button?
In Exercises Controller You could get array of users who have already been assigned to this exercise and add current_user to this array with next updating of this exercise...
Something like that:
def add_user
#exercise = Exercise.includes(:user_ids).where(id: params[:id])
#user_ids = #exercise.user_ids
!#user_ids.index(params[:user][:id]) && #exercise.user_ids = #user_ids.push(params[:user][:id])
...
if #exercise.update_attributes(#user_ids)
redirect_to ...
Related
I have a three tables: User, fruits, user_fruits
There are set number of users and fruits in the world. I cannot create duplicate fruits. Say the fruits already exist in the database, and I want to use them, so I'm not creating new fruits.
Assume we're in a controller and all I want to do is create a new instance of user_fruits. I also want to delete the joined table instance in the destroy action but not the actual fruit itself. Is this the way to do it?
def create
user.user_fruits.create!(fruit: fruit)
end
def destroy
user.user_fruits.find_by(fruit: fruit).destroy!
end
private
attr_reader :fruit
def load_fruit
#fruit = Fruit.find_by(color: red, sweetness: 100)
end
I also want my destroy and create to raise an error if it fails.
If you just want to create a new instance then you can simply use new or build
def create
#new_fruit = user.fruits.new # or fruits.build
end
Update
New instance of user_fruits?
Then you should try something like..
user.user_fruits.new
def create
user.user_fruits.create!(fruit_id: #fruit.id)
end
def destroy
user.user_fruits.find_by_fruit_id(#fruit.id).destroy!
end
And if you want to use reader anyway then replace #fruit with fruit
I have 3 scaffolds that resources are nested as following: mangas > chapters > scans. I'm trying to create a website that allows visitors to read mangas chapters, but I'm getting some difficulties to set up the scan_controller's setter.
I have some constraints to follow: the manga scaffold uses FriendlyId, and both chapters and scans are shown to the URL via their chapter/scan number (an integer)
So, for the manga controller, i did the following:
private
def set_manga
#manga = Manga.friendly.find(params[:id])
end
I simply followed the manuel, no problem whatsoever.
For the chapter_controller, I did this
private
def set_chapter
#manga = Manga.find_by(slug: params[:manga_id])
#chapter = #manga.chapters.find_by(chapter_number: params[:id])
end
This allows me to get all chapters that are linked to the manga I want, and only them. Plus, I get to pass the chapter_number as an id into the link.
And, lastly, I tried this for the scan_controller:
private
def set_scan
#manga = Manga.find_by(slug: params[:manga_id])
#chapter = #manga.chapters.find_by(chapter_number: params[:id])
#scan = #manga.chapters.scans.find(params[:id])
end
However, at this point, I can't get a satisfying result. With this configuration, I get undefined method 'pejis' for #<Chapter::ActiveRecord_Associations_CollectionProxy:0x0000000713d1a0>. I tried to also set as follow:
private
def set_scan
#chapter = Chapter.find_by(chapter_number: params[:id])
#scan = #chapter.scans.find_by(scan_number: params[:id])
end
But i get undefined method 'pejis' for nil:NilClass, which is weird because it doesn't return any error with predefined ids in the rails console.
As anyone an idea ?
Thank you in advance
So, after re-reading again and again my code, I simply needed to do the following:
def set_peji
#chapter = Chapter.find_by(chapter_number: params[:chapter_id])
#peji = #chapter.pejis.find_by(scan_number: params[:id])
end
So I had to remove #manga since it's not concerned anymore, then to set the scan's chapter_id as being the chapter's number.
I have a user_id column. Instead of calling for all members how can I call up members based on current user's and user_id?
This is my controller, I tried changing .all to user_id or current_user.id plus many variations based on examples. Still can't get it. I also have no models (using authrocket). The create action also works and inserts the user_id, I have a def current_user at the bottom.
class Members::MainsController < ApplicationController
# Member Profile List
def index
#members_mains.user_id = current_user.id
#members_mains = Members::Main.all
end
private
# Common Callbacks
def set_members_main
#members_main = Members::Main.find(params[:id])
end
# White List
def members_main_params
params.require(:members_main).permit(:mfirstname, :mlastname, :mtitle, :memail, :mphone, :mnotes, :smfacebook, :smtwitter, :smlinkedin, :user_id)
end
end
If I got it right, your index action should be something like this:
# Member Profile List
def index
#current_member = Members::Main.find(current_user.id)
end
Do you intend to show a list of profiles for all members?
If not, your index action can simply be removed. If so, you wouldn't normally filter on a user_id at all for that action and you can remove that line.
To load a member profile for a specific user_id, try a show action something like this:
def show
#members_main = Members::Main.find_by(user_id: params[:id])
end
That will load a member profile based on the :id from the URL.
If you want to just show the current user's own profile instead, use current_user.id which will give you the AuthRocket user's ID.
def show
#members_main = Members::Main.find_by(user_id: current_user.id)
end
In either case, you may need to remove :show from the set_members_main callback.
Lastly, you probably want to remove :user_id from members_main_params so that users can't modify the AuthRocket user_id. You only want to control that directly (as you already are in the create action).
Hopefully that's clear enough to get you on your way, but I could be off a bit based on what functionality you actually intend for index and show.
I am expanding the sample application of Michael Hartl's Rails Tutorial, which you can find here http://ruby.railstutorial.org/chapters/. The objective of the tutorial is to create a twitter-like website, therefore some of the models are User, Micropost and Relationship, where the last one is intended to establish the relationships of follower and followed among the users (just like in twitter) and to define the logic for retrieveng microposts from the database according the user.
That being said, I want to expand the sample application adding the following functionality:
When writing a micropost, this can be retrieved either by all the user's followers by default or by specific followers whose user names are explicitly included in the content of the micropost, with each name preceded by # symbol.
Example:
User ExampleUser posted two microposts:
micropost_1 with content "hello world" will appear in the micropost feed of every follower.
micropost_2 with content "hello world #john #peter" will appear only in peter's and john's micropost feeds (as long as peter and john are the names of actual users that follow ExampleUser).
In order to achieve this objective, so far I have done the following:
1) I added the field "receivers" of type text to the Micropost model through the console lines:
rails g migration AddReceiverToMicropost receivers:text
rake db:migrate
And then I added the following line to the Micropost model
class Micropost < ActiveRecord::Base
serialize :receivers
This allows me to save an array in the receivers field thanks to the serialize functionality (for this I based in the following site: http://amberonrails.com/storing-arrays-in-a-database-field-w-rails-activerecord/)
Thus, I would be able to store a string array with the receivers' names for a given micropost.
2) Next, I tried to solve the problem of extracting the receivers' names from a micropost's content. So I went to the MicropostsController and created the following method:
private
def get_receivers(content)
receivers = []
i = 0
i0 = 0
while i < content.length do
i = content.index('#',i0)
if i.nil?
break
else
i0 = content.index(' ',i)
if i0.nil?
unless i + 1 == content.length
receivers << content[i+1..-1]
end
break
else
unless i + 1 == i0
receivers << content[i+1..i0-1]
end
end
end
end
receivers
end
and then I applied it withing the MicropostsController's create method:
def create
#micropost = current_user.microposts.build(micropost_params)
if #micropost.save
#micropost.update(receivers: get_receivers(#micropost.content)) #this line uses the get_receivers method to set the receivers field
flash[:success] = "Micropost created!"
redirect_to root_url
else
#feed_items = []
render 'static_pages/home'
end
end
The line followed by the comment is the added one.
So far this works properly.
3) Finnaly I tried to update the method that retrieves all the micropost feed of a user (properly signed-in) in order to implement the new functionality. The method is a class method called from_users_followed_by(user), defined in the Micropost model class, and this is the original code (as it appears in the tutorial):
def self.from_users_followed_by(user)
followed_user_ids = "SELECT followed_id FROM relationships
WHERE follower_id = :user_id"
where("user_id IN (#{followed_user_ids}) OR user_id = :user_id",
user_id: user.id)
end
This method is invoked by the feed method of User class, here is the code:
class User < ActiveRecord::Base
.
.
.
def feed
Micropost.from_users_followed_by(self)
end
And finally, feed in turn is invoked within the home method of the StaticPagesController in response to a request of displaying the sites's homepage provided that a user is properly signed-in at the moment:
class StaticPagesController < ApplicationController
def home
if signed_in?
#micropost = current_user.microposts.build
#feed_items = current_user.feed.paginate(page: params[:page])
end
end
So, you can see that the original self.from_users_followed_by(user) method retrieves all the user's followed users' microposts plus his own microposts. But in order to add the receivers filter layer, I updated it to this new version:
def self.from_users_followed_by(user)
followed_user_ids = "SELECT followed_id FROM relationships
WHERE follower_id = :user_id"
microposts = where("user_id IN (#{followed_user_ids}) OR user_id = :user_id",
user_id: user.id)
microposts_filtered = []
microposts.each do |m|
if m.receivers.nil? or m.receivers.length == 0 or m.receivers.include? user.name
microposts_filtered << m
end
end
microposts_filtered
end
As you can see, my attempt was to manually filter the microposts of the microposts Relation returned by the where method and pass the approved ones into the array microposts_filtered. I thought this was going to work, but a problem arises in the StaticPagesController's home method in the line
#feed_items = current_user.feed.paginate(page: params[:page])
and this is that an array has no method called paginate, which is a method of ActiveRecord::Relation class. That's the reason for my title question: how can I add this receivers filter layer in the where method in order to keep the Relation as output, since an array does not allow pagination?
Sorry for the long exposition of the problem but I did it this way for the sake of understanding. I would like to know how I could solve this problem or if there are other better approaches to achieve the same results in a better fashion. Improvements for any part of the whole problem (such as a better method to get the user names from a micropost's content) are welcomed. Thanks in advance.
I'm trying to save in Note which Employee was the last editor of a `Note'
In a View, I'm able to access the current employee like this:
<h4><%= current_user.employee.id%></h4>
But, in a Model, I can't use current_user.employee.id.
So, I'm trying this in the User model:
def self.current
Thread.current[:user]
end
def self.current=(user)
Thread.current[:user] = user
end
And this in the Note model:
before_create :record_update
before_update :record_update
protected
def record_update
self.lasteditor_id = User.current.employee.id unless User.current.employee.id.nil?
end
What I'm getting is the last User in the Users table.
Thanks for the help!
current_user gets the logged in user information from the session. You cannot access session variables from model. If you want to update the Note model with the Last employee who viewed it, do it in your controller(most likely show action of your note or any other action you think would be right)
def show
#note = Note.find(params[:id])
#note.update_atribute(:last_viewed_by, current_user.id)
end
You code might look different from above. But this is the idea