How to update an active record in ruby - ruby-on-rails

I want to update status to 1, when user views a message.
i need an active record, to change status to 1 ,where status is 0 and id is current id
Any help is appreciated.
i want to change this query to active record.
UPDATE 'course_queries SET status = '1' WHERE course_queries.id =41 and status=0;

As Nithin mentioned, ActiveRecord is a rails feature. Thus, the following wouldn't work unless you're using the Ruby on Rails framework.
With that said, you could also try:
#course = CourseQuery.where(id: params[:id], status: 0).each do |q|
q.update(status: 1)
end
If you need it all in one line, you could use:
#course = CourseQuery.where(id: params[:id], status: 0).update_all(status: 1)
You can then change the id or status here dynamically. :)
Since these examples use the update and update_all methods, I'd recommend you read up about them. Here's a great article I've found on the differences: Difference between active record methods – update, update_all, update_attribute, update_attributes

Something like this
Using ActiveRecord.
#course_query = CourseQuery.find(params[:id]) #id is 41 from your comment
if #course_query.status == 0
#course_query.status = 1
#course_query.save
end

Related

LIKE statement but skips current post

I'm trying to use the LIKE condition to find similar posts.
Here is my code:
#post = Post.find(params[:id])
#post_gsub = Post.find(params[:id]).name.gsub(/something|something else|something else again/, '')
#related_posts = Post.where("name LIKE '%#{#post_gsub}%'")
But when I pull this into the Rails view, there is currently always one match that shows up, which is the current blog post the user is on. How do I skip that current blog post so that "#related_posts" is only showing unique recommendations and not the post the user is currently on?
You can try chaining the where.not method Considering you're using Rails 3, you can use part of raw SQL:
Post.where('name LIKE ? AND id != ?', "%#{#post_gsub}%", #post.id)
That'll make your query to add a != operator to get every post other than the one with id equal to #post.id.
For rails 3 try
Post.where('name LIKE ? AND id != ?', "%#{#post_gsub}%", #post.id)

Ruby on Rails beginner question : equality

I'm starting to know ROR and I was doing a kind of blog with articles, etc...
I did this code :
def show
id = params[:id]
list = Article.all
is_valid = false
list.all.each do |article|
if article.id == id
#is_valid = true
break
end
end
As you can see, this code just wants to check if the article ID exists or not. So I'm testing equality between id and article.id (which's a model linked to the appropriated table in the database) BUT when I try to use or display #is_valid boolean I saw that article.id == id is FALSE every time, even if article.id = 2 and id = 2. I tried to think about everything that can make this occuring, but I admit I still misunderstand this.
Then I ask you if you know why this is occuring. Of course, an equality like 2 == 2 will change #is_valid to true.
Thank you for your help !
Maybe its because params[:id] it's a string and article.id it's an Integer
(byebug) params
{"controller"=>"admin/my_controller", "action"=>"edit", "id"=>"1"}
And yes it is... "id" is a string "1", so you may try this:
def show
id = params[:id].to_i
list = Article.all
is_valid = false
list.all.each do |article|
if article.id == id
#is_valid = true
break
end
end
end
And maybe could work.
This is the answer to your question,
But if you want to learn a little more about Activerecord you can do this
Article.exists?(params[:id])
and that will do what you are trying to do just with a query against db.
and if you want to get just a simple article
record = Article.find_by(id: params[:id]) #return nil when not exist
if record # if nil will threat like false on ruby
#my code when exist
else
#my code when not exist
end
will work (you also can use find but find will throw an exception ActiveRecord::RecordNotFound when not exists so you have to catch that exception.
Activerecord has many ways to check this you dont need to do it by hand.
def show
#article = Article.find(params[:id])
end
This will create a database query which returns a single row. .find raises a ActiveRecord::NotFound exception if the record is not found. Rails catches this error and shows a 404 page. Article.find_by(id: params[:id]) is the "safe" alternative that does not raise.
Your code is problematic since list = Article.all will load all the records out of the database which is slow and will exhaust the memory on the server if you have enough articles. Its the least effective way possible to solve the task.
If you want to just test for existence use .exists? or .any?. This creates a COUNT query instead of selecting the rows.
Article.where(title: 'Hello World').exists?

Find active record on the bases of any other id

I want to find records on the bases of demo_id from Demojobs model.
def show
#demojob = Demojob.find params[:demo_id] #instead of params[:id]
end
but it shows a error Couldn't find Demojob without an ID
Use .find_by
#demojob = Demojob.find_by(demo_id: params[:demo_id])
EDIT:
For Rails version lower than 4.0.2, use:
#demojob = Demojob.where(demo_id: params[:demo_id]).first

Is it best practice to use update_attribute action in Rails CRUD Show

I can use it but I am sure if it is a good practice to use update_attribute action in Show action in Rails. If its a bad practice please suggest for the best alternatives since I need to update a column of row on every show action.
My code
def show
#package = Package.friendly.find(params[:id])
#pack = Package.where(:category_id => #package.category_id).sample(4)
#setting = Setting.find(1)
counter = #package.counter
count = counter+1
#package.update_attributes(:counter => count)
end
In Rails CRUD convention "show" should route from an HTTP GET. In general, it's best to avoid modifying any state of the database from a GET action. So, to answer your question, no, it's not a best practice to use update_attribute in a show action.
This is really a odd processing to obtain a count and then increment it by values then update it to table
It's make slower into that
For Best Practices You can implement like this
item = Item.find(1)
item.foo_count # => 0
Item.increment_counter(:foo_count, 1)
item.foo_count # => 0
item.reload
item.foo_count # => 1
item.increment(:foo_count)
item.foo_count # => 2
As per your logic the code will be
Package.increment_counter(:counter, 1)
#package.increment(:counter)

In Rails, what is the best way to update a record or create a new one if it doesn't exist?

I have a create statement for some models, but it’s creating a record within a join table regardless of whether the record already exists.
Here is what my code looks like:
#user = User.find(current_user)
#event = Event.find(params[:id])
for interest in #event.interests
#user.choices.create(:interest => interest, :score => 4)
end
The problem is that it creates records no matter what. I would like it to create a record only if no record already exists; if a record does exist, I would like it to take the attribute of the found record and add or subtract 1.
I’ve been looking around have seen something called find_or_create_by. What does this do when it finds a record? I would like it to take the current :score attribute and add 1.
Is it possible to find or create by id? I’m not sure what attribute I would find by, since the model I’m looking at is a join model which only has id foreign keys and the score attribute.
I tried
#user.choices.find_or_create_by_user(:user => #user.id, :interest => interest, :score => 4)
but got
undefined method find_by_user
What should I do?
my_class = ClassName.find_or_initialize_by_name(name)
my_class.update_attributes({
:street_address => self.street_address,
:city_name => self.city_name,
:zip_code => self.zip_code
})
Assuming that the Choice model has a user_id (to associate with a user) and an interest_id (to associate with an interest), something like this should do the trick:
#user = User.find(current_user)
#event = Event.find(params[:id])
#event.interests.each do |interest|
choice = #user.choices.find_or_initialize_by_interest_id(interest.id) do |c|
c.score = 0 # Or whatever you want the initial value to be - 1
end
choice.score += 1
choice.save!
end
Some notes:
You don't need to include the user_id column in the find_or_*_by_*, as you've already instructed Rails to only fetch choices belonging to #user.
I'm using find_or_initialize_by_*, which is essentially the same as find_or_create_by_*, with the one key difference being that initialize doesn't actually create the record. This would be similar to Model.new as opposed to Model.create.
The block that sets c.score = 0 is only executed if the record does not exist.
choice.score += 1 will update the score value for the record, regardless if it exists or not. Hence, the default score c.score = 0 should be the initial value minus one.
Finally, choice.save! will either update the record (if it already existed) or create the initiated record (if it didn't).
find_or_create_by_user_id sounds better
Also, in Rails 3 you can do:
#user.choices.where(:user => #user.id, :interest => interest, :score => 4).first_or_create
If you're using rails 4 I don't think it creates the finder methods like it used to, so find_or_create_by_user isn't created for you. Instead you'd do it like this:
#user = User.find(current_user)
#event = Event.find(params[:id])
for interest in #event.interests
#user.choices.find_or_create_by(:interest => interest) do |c|
c.score ||= 0
c.score += 1
end
end
In Rails 4
You can use find_or_create_by to get an object(if not exist,it will create), then use update to save or update the record, the update method will persist record if it is not exist, otherwise update record.
For example
#edu = current_user.member_edu_basics.find_or_create_by(params.require(:member).permit(:school))
if #edu.update(params.require(:member).permit(:school, :majoy, :started, :ended))

Resources